ZQuest Classic Coverage Report


Directory: src/
File: src/zq/zquest.cpp
Date: 2026-01-24 00:14:48
Exec Total Coverage
Lines: 1950 13142 14.8%
Functions: 44 669 6.6%
Branches: 1109 10030 11.1%

Line Branch Exec Source
1 #include "allegro/gui.h"
2 #include "base/files.h"
3 #include "base/mapscr.h"
4 #include "dialog/edit_region.h"
5
6 #include <memory>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <cstring>
10 #include <sstream>
11 #include <ctype.h>
12 #include <assert.h>
13 #include <time.h>
14 #include <vector>
15 #include <filesystem>
16 #include <base/new_menu.h>
17
18 #include "dialog/info_lister.h"
19 #include "zq/commands.h"
20 #include "zq/render_map_view.h"
21 #ifdef __APPLE__
22 // malloc.h is deprecated, but malloc also lives in stdlib
23 #include <stdlib.h>
24 #else
25 #include <malloc.h>
26 #endif
27
28 #include "zalleg/zalleg.h"
29 #include "base/qrs.h"
30 #include "base/dmap.h"
31 #include "base/msgstr.h"
32 #include "base/packfile.h"
33 #include "base/cpool.h"
34 #include "base/autocombo.h"
35 #include "base/render.h"
36 #include "base/version.h"
37 #include "zq/autocombo/autopattern_base.h"
38 #include "zq/autocombo/pattern_basic.h"
39 #include "zq/autocombo/pattern_flatmtn.h"
40 #include "zq/autocombo/pattern_fence.h"
41 #include "zq/autocombo/pattern_cakemtn.h"
42 #include "zq/autocombo/pattern_relational.h"
43 #include "zq/autocombo/pattern_dungeoncarve.h"
44 #include "zq/autocombo/pattern_dormtn.h"
45 #include "zq/autocombo/pattern_tiling.h"
46 #include "zq/autocombo/pattern_replace.h"
47 #include "zq/autocombo/pattern_denseforest.h"
48 #include "zq/autocombo/pattern_extend.h"
49 #include "zq/render_hotkeys.h"
50 #include "zq/render_minimap.h"
51 #include "zq/render_tooltip.h"
52 #include "base/misctypes.h"
53 #include "parser/Compiler.h"
54 #include "base/zc_alleg.h"
55 #include "particles.h"
56 #include "dialog/combopool.h"
57 #include "dialog/alertfunc.h"
58 #include "zq/gui/edit_autocombo.h"
59
60 #include <al5_img.h>
61 #include <loadpng.h>
62 #include <fmt/format.h>
63
64 #include "dialog/cheat_codes.h"
65 #include "dialog/set_password.h"
66 #include "dialog/quest_rules.h"
67 #include "dialog/script_rules.h"
68 #include "dialog/headerdlg.h"
69 #include "dialog/ffc_editor.h"
70 #include "dialog/screen_data.h"
71 #include "dialog/edit_dmap.h"
72 #include "dialog/compilezscript.h"
73 #include "dialog/screen_enemies.h"
74 #include "dialog/enemypattern.h"
75 #include "dialog/sfxdata.h"
76 #include "dialog/mapstyles.h"
77 #include "dialog/externs.h"
78
79 #include "base/gui.h"
80 #include "gui/jwin_a5.h"
81 #include "gui/jwin.h"
82 #include "zc_list_data.h"
83 #include "gui/editbox.h"
84 #include "zq/zq_misc.h"
85 #include "zq/zq_tiles.h" // tile and combo code
86
87 #include "zq/zquest.h"
88 #include "zq/ffasm.h"
89 #include "zq/render.h"
90
91 // the following are used by both zelda.cc and zquest.cc
92 #include "base/zdefs.h"
93 #include "base/qrs.h"
94 #include "tiles.h"
95 #include "base/colors.h"
96 #include "base/qst.h"
97 #include "base/zsys.h"
98 #include "base/zapp.h"
99 #include "base/process_management.h"
100 #include "play_midi.h"
101 #include "sound/zcmusic.h"
102
103 #include "midi.h"
104 #include "sprite.h"
105 #include "fontsdat.h"
106 #include "base/jwinfsel.h"
107 #include "zq/zq_class.h"
108 #include "subscr.h"
109 #include "zq/zq_subscr.h"
110 #include "zc/ffscript.h"
111 #include "gui/EditboxNew.h"
112 #include "sfx.h"
113 #include "zq/zq_custom.h" // custom items and guys
114 #include "zq/zq_strings.h"
115 #include "zq/questReport.h"
116 #include <fstream>
117 #include "drawing.h"
118 #include "zconsole/ConsoleLogger.h"
119 #include "colorname.h"
120 #include "zq/zq_hotkey.h"
121 #include "zq/package.h"
122 #include "zq/zq_files.h"
123 #include "music_playback.h"
124
125 //Windows mmemory tools
126 #ifdef _WIN32
127 #include <windows.h>
128 #include <stdio.h>
129 #include <psapi.h>
130 #pragma comment(lib, "psapi.lib") // Needed to avoid linker issues. -Z
131 #endif
132
133 #ifdef __EMSCRIPTEN__
134 #include <emscripten/emscripten.h>
135 #endif
136
137 #define MIDI_TRACK_BUFFER_SIZE 50
138 extern CConsoleLoggerEx parser_console;
139
140 using ZScript::disassembled_script_data;
141 void write_script(vector<shared_ptr<ZScript::Opcode>> const& zasm, string& dest,
142 bool commented, map<string,disassembled_script_data>* scr_meta_map);
143
144 namespace fs = std::filesystem;
145
146 #if defined(ALLEGRO_WINDOWS)
147 static const char *data_path_name = "win_data_path";
148 static const char *midi_path_name = "win_midi_path";
149 static const char *image_path_name = "win_image_path";
150 static const char *tmusic_path_name = "win_tmusic_path";
151 static const char *last_quest_name = "win_last_quest";
152 static const char *qtname_name = "win_qtname%d";
153 static const char *qtpath_name = "win_qtpath%d";
154 #elif defined(ALLEGRO_LINUX)
155 static const char *data_path_name = "linux_data_path";
156 static const char *midi_path_name = "linux_midi_path";
157 static const char *image_path_name = "linux_image_path";
158 static const char *tmusic_path_name = "linux_tmusic_path";
159 static const char *last_quest_name = "linux_last_quest";
160 static const char *qtname_name = "linux_qtname%d";
161 static const char *qtpath_name = "linux_qtpath%d";
162 #elif defined(__APPLE__)
163 static const char *data_path_name = "macosx_data_path";
164 static const char *midi_path_name = "macosx_midi_path";
165 static const char *image_path_name = "macosx_image_path";
166 static const char *tmusic_path_name = "macosx_tmusic_path";
167 static const char *last_quest_name = "macosx_last_quest";
168 static const char *qtname_name = "macosx_qtname%d";
169 static const char *qtpath_name = "macosx_qtpath%d";
170 #endif
171
172 #include "base/win32.h"
173
174 #include "zq/zq_init.h"
175 #include "zq/zq_doors.h"
176 #include "zq/zq_cset.h"
177 #include "zinfo.h"
178
179 #ifdef _MSC_VER
180 #include <crtdbg.h>
181
182 #endif
183
184 // MSVC fix
185 #if _MSC_VER >= 1900
186 FILE _iob[] = { *stdin, *stdout, *stderr };
187 extern "C" FILE * __cdecl __iob_func(void) { return _iob; }
188 #endif
189
190 extern byte monochrome_console;
191
192 #include "zconsole/ConsoleLogger.h"
193
194 extern CConsoleLoggerEx zscript_coloured_console;
195
196 uint8_t console_is_open = 0;
197 bool is_zq_replay_test = false;
198
199 #include "base/util.h"
200
201 #ifdef __EMSCRIPTEN__
202 #include "base/emscripten_utils.h"
203 #endif
204
205 using namespace util;
206
207 using std::vector;
208 using std::map;
209 using std::stringstream;
210
211 12 FFScript FFCore;
212
213 void load_size_poses();
214 void do_previewtext();
215 bool do_slots(vector<shared_ptr<ZScript::Opcode>> const& zasm,
216 map<string, disassembled_script_data> &scripts, int assign_mode);
217
218 int32_t tooltip_timer=0, tooltip_maxtimer=30, tooltip_current_ffc=0;
219 int32_t combobrushoverride=-1;
220 ComboPosition mouse_combo_pos;
221
222 int32_t original_playing_field_offset=0;
223 12 int32_t playing_field_offset=original_playing_field_offset;
224 int32_t passive_subscreen_height=56;
225
226 bool disable_saving=false, OverwriteProtection;
227 bool halt=false;
228 bool show_sprites=true;
229 bool show_hitboxes = false;
230 bool zq_ignore_item_ownership = true;
231
232 // Used to find FFC script names
233 vector<string> asffcscripts;
234 vector<string> asglobalscripts;
235 vector<string> asitemscripts;
236 vector<string> asnpcscripts;
237 vector<string> aseweaponscripts;
238 vector<string> aslweaponscripts;
239 vector<string> asplayerscripts;
240 vector<string> asdmapscripts;
241 vector<string> asscreenscripts;
242 vector<string> asitemspritescripts;
243 vector<string> ascomboscripts;
244 vector<string> asgenericscripts;
245 vector<string> assubscreenscripts;
246
247 vector<string> ZQincludePaths;
248
249 int32_t CSET_SIZE = 16;
250 int32_t CSET_SHFT = 4;
251 //editbox_data temp_eb_data;
252 /*
253 #define CSET(x) ((x)<<CSET_SHFT)
254 #define csBOSS 14
255 */
256
257 /*
258 enum { m_block, m_coords, m_flags, m_guy, m_warp, m_misc, m_layers,
259 m_menucount };
260 */
261 void update_combo_cycling();
262 void update_freeform_combos();
263
264 /*
265 #define MAXMICE 14
266 #define MAXARROWS 8
267 #define SHADOW_DEPTH 2
268 */
269 int32_t coord_timer=0, coord_frame=0;
270 int32_t blackout_color, zq_screen_w, zq_screen_h;
271 int32_t draw_mode=0;
272
273 12 size_and_pos minimap;
274 12 size_and_pos real_minimap;
275
276 12 size_and_pos minimap_zoomed;
277 12 size_and_pos real_minimap_zoomed;
278
279 12 size_and_pos map_page_bar[9];
280 int32_t mappage_count = 9;
281
282 12 size_and_pos combolist[MAX_COMBO_COLS];
283 12 size_and_pos combolistscrollers[MAX_COMBO_COLS];
284 int32_t num_combo_cols = MAX_COMBO_COLS;
285
286 static bool zoom_in_btn_disabled;
287 static bool zoom_out_btn_disabled;
288 12 size_and_pos zoominbtn;
289 12 size_and_pos zoomoutbtn;
290 12 size_and_pos compactbtn;
291 12 size_and_pos mainbar;
292
293 12 size_and_pos screrrorpos;
294
295 12 size_and_pos comboaliaslist[MAX_COMBO_COLS];
296 12 size_and_pos comboalias_preview;
297 12 size_and_pos combopool_preview;
298 12 size_and_pos combopool_prevbtn;
299
300 12 size_and_pos combo_merge_btn;
301
302 12 size_and_pos combo_preview;
303 12 size_and_pos combo_preview2;
304 12 size_and_pos combo_preview_text1;
305 12 size_and_pos combo_preview_text2;
306 12 size_and_pos combolist_window;
307 12 size_and_pos drawmode_btn;
308 12 size_and_pos main_panel;
309 12 size_and_pos squares_panel;
310 12 size_and_pos preview_panel;
311 12 size_and_pos layer_panel;
312 12 size_and_pos preview_text;
313
314 12 size_and_pos favorites_window;
315 12 size_and_pos favorites_list;
316 12 size_and_pos favorites_x;
317 12 size_and_pos favorites_infobtn;
318 12 size_and_pos favorites_zoombtn;
319 12 size_and_pos favorites_pgleft;
320 12 size_and_pos favorites_pgright;
321
322 12 size_and_pos commands_window;
323 12 size_and_pos commands_list;
324 12 size_and_pos commands_x;
325 12 size_and_pos commands_infobtn;
326 12 size_and_pos commands_zoombtn;
327 12 size_and_pos commands_txt;
328
329 12 size_and_pos squarepanel_swap_btn;
330 12 size_and_pos squarepanel_up_btn;
331 12 size_and_pos squarepanel_down_btn;
332 12 size_and_pos itemsqr_pos;
333 12 size_and_pos flagsqr_pos;
334 12 size_and_pos stairsqr_pos;
335 12 size_and_pos warparrival_pos;
336 12 size_and_pos warpret_pos[4];
337 12 size_and_pos enemy_prev_pos;
338
339 12 size_and_pos txtoffs_single;
340 12 size_and_pos txtoffs_double_1;
341 12 size_and_pos txtoffs_double_2;
342 int32_t panel_align = 1;
343
344 int32_t command_buttonwidth = 88;
345 int32_t command_buttonheight = 19;
346
347 int32_t layerpanel_buttonwidth = 58;
348 int32_t layerpanel_buttonheight = 16;
349
350 int32_t layerpanel_checkbox_hei = 13;
351 int32_t layerpanel_checkbox_wid = 13;
352
353 int32_t favorite_combos[MAXFAVORITECOMBOS];
354 byte favorite_combo_modes[MAXFAVORITECOMBOS];
355 bool ShowFavoriteComboModes;
356 byte FavoriteComboPage;
357
358 char comboprev_buf[512] = {0};
359 char comboprev_buf2[512] = {0};
360 FONT* txfont;
361
362 int32_t mouse_scroll_h;
363
364 // 'mapscreen' refers to the area of the editor where the screen is drawn.
365 int32_t mapscreen_x, mapscreen_y, showedges, showallpanels;
366 // The scale of the entire mapscreen area. This varies based on compact/extended mode.
367 static int mapscreen_screenunit_scale;
368 // The scale of an individual screen being drawn. This is `mapscreen_screenunit_scale / Map.getViewSize()`.
369 static double mapscreen_single_scale;
370 // 4 is roughly the largest value where things render okay. Beyond that, our low bitmap resolution results in tons
371 // of downsampling. Let users go to 16 anyway.
372 static int mapscreen_num_screens_to_draw_max = 16;
373 // The valid layers for the current screen(s).
374 static bool mapscreen_valid_layers[6];
375
376 struct VisibleScreen
377 {
378 int dx, dy;
379 int xoff, yoff;
380 mapscr* scr;
381 int screen;
382 };
383 static std::vector<VisibleScreen> visible_screens;
384 static VisibleScreen* active_visible_screen = nullptr;
385
386 static void set_active_visible_screen(mapscr* scr)
387 {
388 active_visible_screen = nullptr;
389 for (auto& visible_screen : visible_screens)
390 {
391 if (visible_screen.scr == scr)
392 {
393 active_visible_screen = &visible_screen;
394 break;
395 }
396 }
397 }
398
399 static ComboPosition get_mapscreen_mouse_combo_pos()
400 {
401 int startxint = mapscreen_x+(showedges?int(16*mapscreen_single_scale):0);
402 int startyint = mapscreen_y+(showedges?int(16*mapscreen_single_scale):0);
403 int cx = (gui_mouse_x()-startxint)/(16*mapscreen_single_scale);
404 int cy = (gui_mouse_y()-startyint)/(16*mapscreen_single_scale);
405 return ComboPosition{cx, cy};
406 }
407
408 static void refresh_visible_screens()
409 {
410 int num_screens = Map.getViewSize();
411 int screen_width = mapscreenbmp->w * mapscreen_single_scale;
412 int screen_height = mapscreenbmp->h * mapscreen_single_scale;
413
414 visible_screens.clear();
415 for (int dx = 0; dx < num_screens; dx++)
416 {
417 for (int dy = 0; dy < num_screens; dy++)
418 {
419 int mx = Map.getViewScr()%16 + dx;
420 int my = Map.getViewScr()/16 + dy;
421 if (mx < 0 || mx >= 16 || my < 0 || my >= 9)
422 continue;
423
424 int screen = Map.getViewScr() + dx + dy * 16;
425 if (screen >= MAPSCRS)
426 continue;
427
428 mapscr* scr = Map.Scr(screen);
429 int offx = dx * screen_width;
430 int offy = dy * screen_height;
431 visible_screens.emplace_back(VisibleScreen{dx, dy, offx, offy, scr, screen});
432 }
433 }
434
435 for (int i = 0; i < 6; i++)
436 {
437 mapscreen_valid_layers[i] = false;
438 for (auto& vis_screen : visible_screens)
439 {
440 mapscreen_valid_layers[i] |= vis_screen.scr->layermap[i] > 0;
441 }
442 }
443 }
444
445 int32_t readsize, writesize;
446 bool fake_pack_writing=false;
447
448 int32_t showxypos_x;
449 int32_t showxypos_y;
450 int32_t showxypos_w;
451 int32_t showxypos_h;
452 int32_t showxypos_color;
453 int32_t showxypos_ffc=-1000;
454 bool showxypos_icon=false;
455
456 int32_t showxypos_cursor_x;
457 int32_t showxypos_cursor_y;
458 bool showxypos_cursor_icon=false;
459 int32_t showxypos_cursor_color;
460 bool showxypos_dummy = false;
461
462 bool canfill=true; //to prevent double-filling (which stops undos)
463 int32_t lens_hint_item[MAXITEMS][2]; //aclk, aframe
464 int32_t lens_hint_weapon[MAXWPNS][5]; //aclk, aframe, dir, x, y
465 //int32_t mode, switch_mode, orig_mode;
466 int32_t tempmode=GFX_AUTODETECT;
467 RGB_MAP* zq_rgb_table;
468 MIDI *song=NULL;
469 BITMAP *mapscreenbmp, *screen2, *mouse_bmp[MOUSE_BMP_MAX][4], *mouse_bmp_1x[MOUSE_BMP_MAX][4], *icon_bmp[ICON_BMP_MAX][4], *flag_bmp[16][4], *select_bmp[2], *dmapbmp_small, *dmapbmp_large;
470 BITMAP *arrow_bmp[MAXARROWS],*brushbmp, *brushscreen; //*brushshadowbmp;
471 byte *colordata=NULL, *trashbuf=NULL;
472 itemdata *itemsbuf;
473 wpndata *wpnsbuf;
474 comboclass *combo_class_buf;
475 guydata *guysbuf;
476 item_drop_object item_drop_sets[MAXITEMDROPSETS];
477 midi_info Midi_Info;
478 bool zq_showpal=false;
479 bool is_compact = false;
480
481 int pixeldb = 1;
482 int infobg = 1;
483 bool large_merged_combopane = false;
484 bool compact_merged_combopane = true;
485 bool large_zoomed_fav = false;
486 bool compact_zoomed_fav = true;
487 bool large_zoomed_cmd = false;
488 bool compact_zoomed_cmd = true;
489
490 bool compact_square_panels = false;
491 int compact_active_panel = 0;
492
493 int combo_col_scale = 1;
494
495 std::vector<std::shared_ptr<zasm_script>> zasm_scripts;
496 script_data *ffscripts[NUMSCRIPTFFC];
497 script_data *itemscripts[NUMSCRIPTITEM];
498 script_data *guyscripts[NUMSCRIPTGUYS];
499 script_data *lwpnscripts[NUMSCRIPTWEAPONS];
500 script_data *ewpnscripts[NUMSCRIPTWEAPONS];
501 script_data *globalscripts[NUMSCRIPTGLOBAL];
502 script_data *genericscripts[NUMSCRIPTSGENERIC];
503 script_data *playerscripts[NUMSCRIPTHERO];
504 script_data *screenscripts[NUMSCRIPTSCREEN];
505 script_data *dmapscripts[NUMSCRIPTSDMAP];
506 script_data *itemspritescripts[NUMSCRIPTSITEMSPRITE];
507 script_data *comboscripts[NUMSCRIPTSCOMBODATA];
508 script_data *subscreenscripts[NUMSCRIPTSSUBSCREEN];
509
510 extern string zScript;
511 char zScriptBytes[512];
512 char zLastVer[512] = { 0 };
513 SAMPLE customsfxdata[WAV_COUNT];
514 uint8_t customsfxflag[WAV_COUNT>>3];
515 int32_t sfxdat=1;
516
517 int32_t onImport_ComboAlias();
518 int32_t onExport_ComboAlias();
519
520 void set_console_state();
521
522 void clearConsole()
523 {
524 if(!console_is_open) return;
525 zscript_coloured_console.cls(CConsoleLoggerEx::COLOR_BACKGROUND_BLACK);
526 zscript_coloured_console.gotoxy(0,0);
527 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
528 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"ZQuest Classic Logging Console\n");
529 }
530
531 void initConsole()
532 {
533 if(console_is_open) return;
534 console_is_open = 1;
535 set_console_state();
536 zscript_coloured_console.Create("ZQuest Classic Logging Console", 600, 200);
537 clearConsole();
538 }
539
540 11 void killConsole()
541 {
542
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(!console_is_open) return;
543 console_is_open = 0;
544 set_console_state();
545 zscript_coloured_console.kill();
546 11 }
547
548 int toggleConsole()
549 {
550 console_is_open ? killConsole() : initConsole();
551 zc_set_config("zquest","open_debug_console",console_is_open?1:0);
552 return D_O_K;
553 }
554
555 int showHotkeys()
556 {
557 hotkeys_run();
558 return D_O_K;
559 }
560
561 extern map_and_screen map_page[MAX_MAPPAGE_BTNS];
562
563 int32_t do_OpenQuest()
564 {
565 return onOpen();
566 }
567
568 int32_t do_NewQuest()
569 {
570 //clear the panel recent screen buttons to prevent crashes from invalid maps
571 for ( int32_t q = 0; q < 9; q++ )
572 {
573 map_page[q].map = 0;
574 map_page[q].screen = 0;
575 }
576 Map.setCurrMap(0);
577 Map.setCurrScr(0);
578 return onNew();
579 }
580
581 extern int CheckerCol1, CheckerCol2;
582 int32_t alignment_arrow_timer=0;
583 int32_t Flip=0,Combo=0,CSet=2,current_combolist=0,current_comboalist=0,current_cpoollist=0,current_cautolist=0,current_mappage=0;
584 int32_t Flags=0,Flag=0,menutype=(m_block);
585 int MouseScroll = 0, SavePaths = 0, CycleOn = 0, ShowGrid = 0, ShowScreenGrid = 0, ShowRegionGrid = 0, GridColor = 15, ShowCurScreenOutline = 1,
586 CmbCursorCol = 15, TilePgCursorCol = 15, CmbPgCursorCol = 15, TTipHLCol = 13,
587 TileProtection = 0, ComboProtection = 0, NoScreenPreview = 0, MMapCursorStyle = 0,
588 LayerDitherBG = -1, LayerDitherSz = 2, RulesetDialog = 0,
589 EnableTooltips = 0, TooltipsHighlight = 0, ShowFFScripts = 0, ShowSquares = 0,
590 ShowFFCs = 0, ShowInfo = 0, skipLayerWarning = 0,
591 DisableLPalShortcuts = 1, DisableCompileConsole = 0, numericalFlags = 0,
592 ActiveLayerHighlight = 0, DragCenterOfSquares = 0, SmartFFCPlacement = 0;
593 uint8_t InvalidBG = 0;
594 bool NoHighlightLayer0 = false;
595 // If true, uses "MapViewRTI" to draw editor screens. This allows for multiples palettes on the
596 // screen at once, and for higher resolution.
597 // Note: this is the default currently, and eventually the option should be removed and the
598 // "low-quality" rendering removed. Hasn't been done just yet just in case this causes regressions.
599 bool HighQualityScreenRendering = true;
600 int32_t FlashWarpSquare = -1, FlashWarpClk = 0; // flash the destination warp return when ShowSquares is active
601 uint8_t ViewLayer3BG = 0, ViewLayer2BG = 0;
602 int32_t window_width, window_height;
603 bool ShowFPS = false, SaveDragResize = false, DragAspect = false, SaveWinPos=false;
604 bool allowHideMouse = false;
605 double aspect_ratio = LARGE_H / double(LARGE_W);
606 int window_min_width = 0, window_min_height = 0;
607 int32_t ComboBrush = 0; //show the brush instead of the normal mouse
608 int32_t ComboBrushPause = 0; //temporarily disable the combo brush
609 int32_t FloatBrush = 0; //makes the combo brush float a few pixels up and left
610 int AutoBrush = 0; //Drag to size the brush on the combo panes
611 bool AutoBrushRevert = false; //Revert after placing
612 int LinkedScroll = 0;
613 //complete with shadow
614 int32_t OpenLastQuest = 0; //makes the program reopen the quest that was
615 //open at the time you quit
616 int32_t ShowMisalignments = 0; //makes the program display arrows over combos that are
617 //not aligned with the next screen.
618 int32_t AnimationOn = 0; //animate the combos in zquest?
619 int32_t AutoBackupRetention = 0; //use auto-backup feature? if so, how many backups (1-10) to keep
620 int32_t AutoSaveInterval = 0; //how often a timed autosave is made (not overwriting the current file)
621 int32_t UncompressedAutoSaves = 0; //should timed saves be uncompressed/encrypted?
622 int32_t KeyboardRepeatDelay = 0; //the time in milliseconds after holding down a key that the key starts to repeat
623 int32_t KeyboardRepeatRate = 0; //the time in milliseconds between each repetition of a repeated key
624
625 time_t auto_save_time_start, auto_save_time_current;
626 double auto_save_time_diff = 0;
627 int32_t AutoSaveRetention = 0; //how many autosaves of a quest to keep
628 int32_t ImportMapBias = 0; //tells what has precedence on map importing
629 int32_t BrushWidth=1, BrushHeight=1;
630 bool saved = true, autosaved = true;
631 bool __debug=false;
632 int32_t LayerMaskInt[7]={0};
633 int32_t CurrentLayer=0;
634 int32_t DuplicateAction[4]={0};
635 int32_t OnlyCheckNewTilesForDuplicates = 0;
636 int32_t try_recovering_missing_scripts = 0;
637
638 uint8_t PreFillTileEditorPage = 0, PreFillComboEditorPage = 0;
639 int32_t DMapEditorLastMaptileUsed = 0;
640
641 /*
642 , HorizontalDuplicateAction;
643 int32_t VerticalDuplicateAction, BothDuplicateAction;
644 */
645 word msg_count = 0;
646 int32_t LeechUpdate = 0;
647 int32_t LeechUpdateTiles = 0;
648 int32_t SnapshotFormat = 0;
649 byte SnapshotScale = 0;
650
651 byte Color = 0;
652 extern int32_t jwin_pal[jcMAX];
653 int32_t gui_colorset=99;
654
655 static int32_t combo_apos=0; //currently selected combo alias
656 int32_t alias_origin=0;
657 int32_t alias_cset_mod=0;
658
659 static int32_t combo_pool_pos=0; //currently selected combo pool
660 bool weighted_cpool = true;
661 bool cpool_prev_visible = false;
662
663 static int32_t combo_auto_pos=0; //currently selected autocombo
664 byte cauto_height = 1;
665
666 bool trip=false;
667
668 int32_t fill_type=1;
669
670 bool first_save=false;
671 char *filepath,*midipath,*datapath,*imagepath,*tmusicpath,*last_timed_save;
672 string helpstr, zstringshelpstr;
673
674 ZCMUSIC *zcmusic = NULL;
675 ZCMIXER *zcmixer = NULL;
676 int32_t midi_volume = 255;
677 extern int32_t prv_mode;
678 int32_t prv_warp = 0;
679 int32_t prv_twon = 0;
680
681 int32_t Frameskip = 0, RequestedFPS = 60, zqUseWin32Proc = 1;
682 int32_t zqColorDepth = 8;
683
684 11 void set_last_timed_save(char const* buf)
685 {
686
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11 if(buf && buf[0])
687 {
688 if(buf != last_timed_save)
689 strcpy(last_timed_save, buf);
690 }
691 else
692 {
693 11 last_timed_save[0] = 0;
694 11 buf = nullptr;
695 }
696 11 zc_set_config("zquest","last_timed_save",buf);
697 11 }
698
699 17 void mark_save_dirty()
700 {
701 17 saved = false;
702 17 autosaved = false;
703 17 }
704
705 void loadlvlpal(int32_t level);
706 bool get_debug()
707 {
708 return __debug;
709 //return true;
710 }
711
712 void set_debug(bool d)
713 {
714 __debug=d;
715 return;
716 }
717
718 bool handle_quit()
719 {
720 if(onExit()==D_CLOSE)
721 return (exiting_program = true);
722 return false;
723 }
724 bool handle_close_btn_quit()
725 {
726 if(close_button_quit)
727 {
728 close_button_quit=false;
729 return handle_quit();
730 }
731 return false;
732 }
733 // **** Timers ****
734
735 volatile int32_t lastfps=0;
736 volatile int32_t framecnt=0;
737 size_t cpoolbrush_index = 0;
738
739 // quest data
740 12 zquestheader header;
741 zctune customtunes[MAXCUSTOMMIDIS];
742 byte *quest_file;
743 int32_t msg_strings_size;
744 //emusic *enhancedMusic;
745 ZCHEATS zcheats;
746 byte use_cheats;
747 byte use_tiles;
748 // Note: may not be null-terminated (must refactor writecolordata to fix).
749 char palnames[MAXLEVELS][17];
750 char zquestdat_sig[52];
751 char qstdat_str[2048];
752
753 int32_t gme_track=0;
754
755 int32_t dlevel; // just here until gamedata is properly done
756
757 12 bool bad_version(int32_t ver)
758 {
759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(ver < 0x170)
760 return true;
761
762 12 return false;
763 12 }
764
765 // These are for drawing eyeballs correctly in combo_tile.
766 zfix HeroModifiedX()
767 {
768 return gui_mouse_x() - 7;
769 }
770 zfix HeroModifiedY()
771 {
772 return gui_mouse_y() - 7;
773 }
774
775
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu import_250_menu
776 48 {
777
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onImport_DMaps },
778
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Table", onImport_Combos },
779
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Alias", onImport_ComboAlias },
780 };
781
782
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu import_graphics
783 180 {
784
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palettes", onImport_Pals },
785
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
786
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Tileset (&Full)", onImport_Tiles },
787
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tile Pack", onImport_Tilepack },
788
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "T&ile Pack to...", onImport_Tilepack_To },
789
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
790
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Set (Range)", onImport_Combos },
791
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo Pack (Full, 1:1)", onImport_Combopack },
792
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo Pack to... (Dest)", onImport_Combopack_To },
793
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
794
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo &Alias Pack", onImport_Comboaliaspack },
795
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo A&lias Pack to...", onImport_Comboaliaspack_To },
796
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
797
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Doorsets", onImport_Doorset },
798 };
799
800
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu import_menu
801 120 {
802
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onImport_Guys },
803
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map", onImport_Map },
804
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onImport_DMaps },
805
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Strings (.tsv)", onImport_StringsTSV },
806
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "String Table (deprecated)", onImport_Msgs },
807
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
808
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Graphics", &import_graphics },
809
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
810
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2.50 (Broken)", &import_250_menu },
811 };
812
813
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu export_250_menu
814 60 {
815
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onExport_DMaps },
816
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Table", onExport_Combos },
817
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Alias", onExport_ComboAlias },
818
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Graphics Pack", onExport_ZGP },
819 };
820
821
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu zq_help_menu
822 36 {
823
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Editor Help", onHelp },
824
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Strings Help", onZstringshelp },
825 };
826
827
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu export_graphics
828 144 {
829
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palettes", onExport_Pals },
830
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
831
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Tileset (&Full)", onExport_Tiles },
832
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tile Pack", onExport_Tilepack },
833
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
834
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Set", onExport_Combos },
835
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo Pack", onExport_Combopack },
836
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
837
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo &Alias Pack", onExport_Comboaliaspack },
838
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
839
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Doorsets", onExport_Doorset },
840 };
841
842
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu export_menu
843 132 {
844 #ifdef _WIN32
845 { "&Package", onExport_Package },
846 #endif
847
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onExport_Guys },
848
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map", onExport_Map },
849
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onExport_DMaps },
850
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
851
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Strings (.tsv)", onExport_StringsTSV },
852
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "String Table (deprecated)", onExport_Msgs },
853
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
854
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Graphics", &export_graphics },
855
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
856
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2.50 (Broken)", &export_250_menu },
857 };
858
859
860
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu recent_menu
861 132 {
862
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
863
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
864
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
865
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
866
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
867
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
868
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
869
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
870
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
871
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
872 };
873 static char rec_menu_fullpaths[10][512];
874 static char rec_menu_strs[10][64];
875
876 int32_t customOpen(char const* path);
877 void do_recent_quest(uint32_t ind)
878 {
879 if(ind > 9) return;
880 strcpy(temppath, rec_menu_fullpaths[ind]);
881 customOpen(temppath);
882 }
883 int32_t do_RecentQuest_0() { do_recent_quest(0); return D_O_K; }
884 int32_t do_RecentQuest_1() { do_recent_quest(1); return D_O_K; }
885 int32_t do_RecentQuest_2() { do_recent_quest(2); return D_O_K; }
886 int32_t do_RecentQuest_3() { do_recent_quest(3); return D_O_K; }
887 int32_t do_RecentQuest_4() { do_recent_quest(4); return D_O_K; }
888 int32_t do_RecentQuest_5() { do_recent_quest(5); return D_O_K; }
889 int32_t do_RecentQuest_6() { do_recent_quest(6); return D_O_K; }
890 int32_t do_RecentQuest_7() { do_recent_quest(7); return D_O_K; }
891 int32_t do_RecentQuest_8() { do_recent_quest(8); return D_O_K; }
892 int32_t do_RecentQuest_9() { do_recent_quest(9); return D_O_K; }
893
894 2 void refresh_recent_menu()
895 {
896 2 int32_t (*procs[10])(void) = {
897 do_RecentQuest_0, do_RecentQuest_1, do_RecentQuest_2, do_RecentQuest_3,
898 do_RecentQuest_4, do_RecentQuest_5, do_RecentQuest_6,
899 do_RecentQuest_7, do_RecentQuest_8, do_RecentQuest_9
900 };
901
5/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
2 static MenuItem nilitem("---",nullptr,nullopt,true);
902
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 20 times.
22 for(auto q = 0; q < 10; ++q)
903 {
904 20 MenuItem& mit = *recent_menu.at(q);
905 20 bool valid = rec_menu_fullpaths[q][0] != '-';
906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if(valid)
907 mit = MenuItem(rec_menu_strs[q],procs[q]);
908 20 else mit = nilitem;
909 20 }
910 2 }
911
912 1 void load_recent_quests()
913 {
914 1 char configname[64] = "rec_qst_";
915 1 char* ptr = &configname[strlen(configname)];
916 1 char buf[512] = {0};
917
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 times.
11 for(auto q = 0; q < 10; ++q)
918 {
919 10 sprintf(ptr, "%d", q); //increment the configname value
920 10 char const* qst_str = zc_get_config("recent",configname,nullptr);
921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(qst_str[0])
922 {
923 strncpy(rec_menu_fullpaths[q], qst_str, 511);
924 relativize_path(buf, rec_menu_fullpaths[q]);
925 if(strlen(buf) > 62)
926 {
927 buf[60] = buf[61] = buf[62] = '.'; //add "..." as the last 3 characters
928 }
929 strncpy(rec_menu_strs[q], buf, 63);
930 }
931 else
932 {
933 10 strcpy(rec_menu_fullpaths[q], "---");
934 10 strcpy(rec_menu_strs[q], "---");
935 }
936 10 rec_menu_fullpaths[q][511] = 0;
937 10 rec_menu_strs[q][63] = 0;
938 10 }
939 1 refresh_recent_menu();
940 1 }
941
942 void write_recent_quests()
943 {
944 char configname[64] = "rec_qst_";
945 char* ptr = &configname[strlen(configname)];
946 for(auto q = 0; q < 10; ++q)
947 {
948 sprintf(ptr, "%d", q); //increment the configname value
949 zc_set_config("recent",configname,(rec_menu_fullpaths[q][0]!='-') ? rec_menu_fullpaths[q] : nullptr);
950 }
951 }
952
953 void update_recent_quest(char const* path)
954 {
955 int32_t ind = -1;
956 for(auto q = 0; q < 10; ++q)
957 {
958 if(!strcmp(path, rec_menu_fullpaths[q]))
959 {
960 ind = q;
961 break;
962 }
963 }
964 if(ind > -1)
965 {
966 for(auto q = ind; q > 0; --q)
967 {
968 strcpy(rec_menu_fullpaths[q], rec_menu_fullpaths[q-1]);
969 strcpy(rec_menu_strs[q], rec_menu_strs[q-1]);
970 }
971 }
972 else
973 {
974 int32_t free_ind = 9; //if none found, override the last index
975 for(auto q = 0; q < 9; ++q)
976 {
977 if(rec_menu_fullpaths[q][0] == '-')
978 {
979 free_ind = q;
980 break;
981 }
982 }
983
984 for(auto q = free_ind; q > 0; --q)
985 {
986 strcpy(rec_menu_fullpaths[q], rec_menu_fullpaths[q-1]);
987 strcpy(rec_menu_strs[q], rec_menu_strs[q-1]);
988 }
989 }
990 char buf[512] = {0};
991 strcpy(rec_menu_fullpaths[0], path);
992 relativize_path(buf, rec_menu_fullpaths[0]);
993 if(strlen(buf) > 62)
994 {
995 buf[60] = buf[61] = buf[62] = '.'; //add "..." as the last 3 characters
996 }
997 strncpy(rec_menu_strs[0], buf, 63);
998 refresh_recent_menu();
999 zc_set_config("zquest",last_quest_name,path);
1000 write_recent_quests();
1001 }
1002
1003 void reload_zq_gui()
1004 {
1005 init_custom_fonts();
1006 load_size_poses();
1007 refresh_visible_screens();
1008 update_combobrush();
1009 refresh(rCLEAR|rALL);
1010 }
1011 void change_mapscr_zoom(int delta)
1012 {
1013 int num_screens = Map.getViewSize();
1014 num_screens = std::clamp(num_screens + delta, 1, mapscreen_num_screens_to_draw_max);
1015 Map.setViewSize(num_screens);
1016 std::string qst_cfg_header = qst_cfg_header_from_path(filepath);
1017 zc_set_config(qst_cfg_header.c_str(), "zoom_num_screens", Map.getViewSize());
1018 reload_zq_gui();
1019 }
1020 void toggle_is_compact()
1021 {
1022 is_compact = !is_compact;
1023 zc_set_config("ZQ_GUI","compact_mode",is_compact?1:0);
1024 reload_zq_gui();
1025 }
1026 void toggle_merged_mode()
1027 {
1028 if(is_compact)
1029 {
1030 compact_merged_combopane = !compact_merged_combopane;
1031 zc_set_config("ZQ_GUI","merge_cpane_compact",compact_merged_combopane?1:0);
1032 }
1033 else
1034 {
1035 large_merged_combopane = !large_merged_combopane;
1036 zc_set_config("ZQ_GUI","merge_cpane_large",large_merged_combopane?1:0);
1037 }
1038 reload_zq_gui();
1039 }
1040 void toggle_compact_sqr_mode()
1041 {
1042 compact_square_panels = !compact_square_panels;
1043 zc_set_config("ZQ_GUI","square_panels_compact",compact_square_panels?1:0);
1044 reload_zq_gui();
1045 }
1046 void cycle_compact_sqr(bool down)
1047 {
1048 if(!(is_compact && compact_square_panels))
1049 return;
1050 static const int num_panels = 3;
1051 if(down)
1052 compact_active_panel = (compact_active_panel+1)%num_panels;
1053 else
1054 compact_active_panel = (compact_active_panel-1+num_panels)%num_panels;
1055 reload_zq_gui();
1056 }
1057 void toggle_favzoom_mode()
1058 {
1059 if(is_compact)
1060 {
1061 compact_zoomed_fav = !compact_zoomed_fav;
1062 zc_set_config("ZQ_GUI","zoom_fav_compact",compact_zoomed_fav?1:0);
1063 }
1064 else
1065 {
1066 large_zoomed_fav = !large_zoomed_fav;
1067 zc_set_config("ZQ_GUI","zoom_fav_large",large_zoomed_fav?1:0);
1068 }
1069 reload_zq_gui();
1070 }
1071 void toggle_cmdzoom_mode()
1072 {
1073 if(is_compact)
1074 {
1075 compact_zoomed_cmd = !compact_zoomed_cmd;
1076 zc_set_config("ZQ_GUI","zoom_cmd_compact",compact_zoomed_cmd?1:0);
1077 }
1078 else
1079 {
1080 large_zoomed_cmd = !large_zoomed_cmd;
1081 zc_set_config("ZQ_GUI","zoom_cmd_large",large_zoomed_cmd?1:0);
1082 }
1083 reload_zq_gui();
1084 }
1085
1086 enum
1087 {
1088 MENUID_FILE_SAVE,
1089 MENUID_FILE_SAVEAS,
1090 MENUID_FILE_REVERT,
1091 };
1092
1093
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu file_menu
1094 156 {
1095
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&New", do_NewQuest },
1096
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Open", do_OpenQuest },
1097
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Recent", &recent_menu },
1098
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1099
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Save", onSave, MENUID_FILE_SAVE },
1100
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Save &as...", onSaveAs, MENUID_FILE_SAVEAS },
1101
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Revert", onRevert, MENUID_FILE_REVERT },
1102
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1103
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Import", &import_menu },
1104
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Export", &export_menu },
1105 #ifndef __EMSCRIPTEN__
1106
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1107
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "E&xit", handle_quit },
1108 #endif
1109 };
1110
1111 enum
1112 {
1113 MENUID_MAPS_NEXT,
1114 MENUID_MAPS_PREV,
1115 };
1116
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu maps_menu
1117 72 {
1118
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Goto Map...", onGotoMap },
1119
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Next Map", onIncMap, MENUID_MAPS_NEXT },
1120
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Previous Map", onDecMap, MENUID_MAPS_PREV },
1121
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1122
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "D&elete Map", onDeleteMap },
1123 };
1124
1125
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu misc_menu
1126 132 {
1127
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "S&ubscreens", onEditSubscreens },
1128
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Shop Types", onShopTypes },
1129
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Bottle Types", onBottleTypes },
1130
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Bottle S&hop Types", onBottleShopTypes },
1131
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Info Types", onInfoTypes },
1132
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Warp Rings", onWarpRings },
1133
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Triforce Pieces", onTriPieces },
1134
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&End String", onEndString },
1135
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Item &Drop Sets", onItemDropSets },
1136
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Save Menus", onSaveMenus },
1137 };
1138
1139
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu spr_menu
1140 48 {
1141
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Sprite Data", onCustomWpns },
1142
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Hero", onCustomHero },
1143
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Misc Sprites", onMiscSprites },
1144 };
1145
1146
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 NewMenu colors_menu
1147 48 {
1148
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Main ", onColors_Main },
1149
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Levels ", onColors_Levels },
1150
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Sprites ", onColors_Sprites },
1151 };
1152
1153
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu defs_menu
1154 108 {
1155
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palettes", onDefault_Pals },
1156
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tiles", onDefault_Tiles },
1157
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combos", onDefault_Combos },
1158
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Items", onDefault_Items },
1159
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onDefault_Guys },
1160
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Sprite Data", onDefault_Weapons },
1161
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map Styles", onDefault_MapStyles },
1162
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "SF&X Data", onDefault_SFX },
1163 };
1164
1165 int32_t onEditComboAlias();
1166 int32_t onEditComboPool();
1167 int32_t onEditAutoCombo();
1168
1169
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu graphics_menu
1170 144 {
1171
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palettes ", &colors_menu },
1172
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Sprites ", &spr_menu },
1173
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combos", onCombos },
1174
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tiles", onTiles },
1175
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Game icons", onIcons },
1176
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Misc co&lors", onMiscColors },
1177
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map styles", onMapStyles },
1178
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Door Combo Sets", onDoorCombos },
1179
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo &Aliases", [](){call_alias_pages(); return D_O_K;} },
1180
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo Pools", [](){call_cpool_pages(); return D_O_K;} },
1181
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Auto Combos", [](){call_autoc_pages(); return D_O_K;} },
1182 };
1183
1184
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu audio_menu
1185 60 {
1186
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "SF&X Data", onSelectSFX },
1187
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Music", onMusic },
1188
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "M&IDIs", onMidis },
1189
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Mis&c SFX", onMiscSFX },
1190 };
1191
1192 void set_rules(byte* newrules);
1193
1194 void call_testqst_dialog();
1195 int32_t onTestQst()
1196 {
1197 call_testqst_dialog();
1198 return D_O_K;
1199 }
1200
1201 int32_t onRulesDlg()
1202 {
1203 call_qr_dialog(21, set_rules);
1204 return D_O_K;
1205 }
1206
1207 int32_t onRulesSearch()
1208 {
1209 call_qrsearch_dialog(set_rules);
1210 return D_O_K;
1211 }
1212
1213 int32_t onZScriptSettings()
1214 {
1215 ScriptRulesDialog(quest_rules, 17, [](byte* newrules)
1216 {
1217 mark_save_dirty();
1218 memcpy(quest_rules, newrules, QR_SZ);
1219 unpack_qrs();
1220 }).show();
1221 return D_O_K;
1222 }
1223
1224 void call_zinf_dlg();
1225 int32_t onZInfo()
1226 {
1227 call_zinf_dlg();
1228 return D_O_K;
1229 }
1230
1231
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu quest_menu
1232 204 {
1233
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Options ", onRulesDlg },
1234
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Test", onTestQst },
1235
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Items", onCustomItems },
1236
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onCustomEnemies },
1237
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Hero", onCustomHero },
1238
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Strings", onStrings },
1239
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&DMaps", onDmaps },
1240
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Map Settings", onMaps },
1241
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "I&nit Data", onInit },
1242
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Misc D&ata ", &misc_menu },
1243
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&ZInfo", onZInfo },
1244
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1245
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Graphics ", &graphics_menu },
1246
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "A&udio ", &audio_menu },
1247
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1248
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "De&faults ", &defs_menu },
1249 };
1250
1251
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu paste_menu
1252 36 {
1253
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste &To All", onPasteToAll },
1254
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste &All To All", onPasteAllToAll },
1255 };
1256
1257
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu paste_item_menu
1258 156 {
1259
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Undercombo", onPasteUnderCombo },
1260
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Secret Combos", onPasteSecretCombos },
1261
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Freeform Combos", onPasteFFCombos },
1262
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Screen &Data", onPasteScreenData },
1263
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Warps", onPasteWarps },
1264
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Warp &Return", onPasteWarpLocations },
1265
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onPasteEnemies },
1266
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Room &Type Data", onPasteRoom },
1267
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Guy/String", onPasteGuy },
1268
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Doo&rs", onPasteDoors },
1269
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Layers", onPasteLayers },
1270
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palette", onPastePalette },
1271 };
1272
1273 enum
1274 {
1275 MENUID_EDIT_UNDO,
1276 MENUID_EDIT_REDO,
1277 MENUID_EDIT_COPY,
1278 MENUID_EDIT_PASTE,
1279 MENUID_EDIT_PASTEALL,
1280 MENUID_EDIT_ADVPASTE,
1281 MENUID_EDIT_SPECPASTE,
1282 MENUID_EDIT_DELETE,
1283 };
1284
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu edit_menu
1285 132 {
1286
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Undo", onUndo, MENUID_EDIT_UNDO },
1287
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Redo", onRedo, MENUID_EDIT_REDO },
1288
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Copy", onCopy, MENUID_EDIT_COPY },
1289
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Paste", onPaste, MENUID_EDIT_PASTE },
1290
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste A&ll", onPasteAll, MENUID_EDIT_PASTEALL },
1291
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Adv. Paste ", &paste_menu, MENUID_EDIT_ADVPASTE },
1292
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste &Spec. ", &paste_item_menu, MENUID_EDIT_SPECPASTE },
1293
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Delete", onDelete, MENUID_EDIT_DELETE },
1294
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1295
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Maps ", &maps_menu },
1296 };
1297
1298
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu drawing_mode_menu
1299 60 {
1300
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Normal", onDrawingModeNormal, dm_normal },
1301
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Alias", onDrawingModeAlias, dm_alias },
1302
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Pool", onDrawingModePool, dm_cpool },
1303
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Auto Combo", onDrawingModeAuto, dm_auto },
1304 };
1305
1306
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu integrity_check_menu
1307 48 {
1308
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&All ", onIntegrityCheckAll },
1309
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Screens ", onIntegrityCheckRooms },
1310
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Warps ", onIntegrityCheckWarps },
1311 };
1312
1313
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu quest_reports_menu
1314 108 {
1315
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Bugged Next-> Combo Locations", onBuggedNextComboLocationReport },
1316
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Locations", onComboLocationReport },
1317
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Combo Type Locations", onComboTypeLocationReport },
1318
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemy Locations", onEnemyLocationReport },
1319
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Item Locations", onItemLocationReport },
1320
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Script Locations", onScriptLocationReport },
1321
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&What Links Here", onWhatWarpsReport },
1322
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "In&tegrity Check ", &integrity_check_menu },
1323 };
1324
1325 int32_t onPalFix();
1326 int32_t onPitFix();
1327 int32_t onStrFix()
1328 {
1329 if(get_qr(qr_OLD_STRING_EDITOR_MARGINS))
1330 {
1331 if (alert_confirm("Fix: Old Margins",
1332 "Fixing margins may cause strings that used to spill outside the textbox"
1333 " to instead be cut off. Are you sure?"))
1334 {
1335 set_qr(qr_OLD_STRING_EDITOR_MARGINS, 0);
1336 mark_save_dirty();
1337 }
1338 }
1339 if(get_qr(qr_STRING_FRAME_OLD_WIDTH_HEIGHT))
1340 {
1341 if (alert_confirm("Fix: Old Frame Size",
1342 "This will fix the frame size of all strings. No visual changes should occur,"
1343 " as the string width/height will be fixed, but the compat QR will also be unchecked."))
1344 {
1345 for(auto q = 0; q < msg_count; ++q)
1346 {
1347 MsgStrings[q].w += 16;
1348 MsgStrings[q].h += 16;
1349 }
1350 set_qr(qr_STRING_FRAME_OLD_WIDTH_HEIGHT, 0);
1351 mark_save_dirty();
1352 }
1353 }
1354 return D_O_K;
1355 }
1356
1357 int32_t onRemoveOldArrivalSquare();
1358 enum
1359 {
1360 MENUID_FIXTOOL_OLDSTRING,
1361 };
1362
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu fixtools_menu
1363 96 {
1364
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Color Set Fix", onCSetFix },
1365
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Liquid Solidity Fix", onWaterSolidity },
1366
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Effect Square Fix", onEffectFix },
1367
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Level Palette Fix", onPalFix },
1368
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Pit and Liquid Damage Fix", onPitFix },
1369
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Old Strings Fix", onStrFix, MENUID_FIXTOOL_OLDSTRING },
1370
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Green Arrival Square Fix", onRemoveOldArrivalSquare },
1371 };
1372
1373
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu tool_menu
1374 132 {
1375
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Combo &Flags", onFlags, nullopt, MFL_EXIT_PRE_PROC },
1376
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fix &Tools ", &fixtools_menu },
1377
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&NES Dungeon Template", onTemplate },
1378
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Apply Template to All", onReTemplate },
1379
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1380
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Preview Mode", onPreviewMode },
1381
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Drawing &Mode ", &drawing_mode_menu },
1382
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1383
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&List Combos Used", onUsedCombos },
1384
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Quest Reports ", &quest_reports_menu },
1385 };
1386
1387 int32_t onLayer3BG()
1388 {
1389 ViewLayer3BG = ViewLayer3BG ? 0 : 1;
1390 zc_set_config("zquest","layer3_bg",ViewLayer3BG);
1391 return D_O_K;
1392 }
1393 int32_t onLayer2BG()
1394 {
1395 ViewLayer2BG = ViewLayer2BG ? 0 : 1;
1396 zc_set_config("zquest","layer2_bg",ViewLayer2BG);
1397 return D_O_K;
1398 }
1399 int onGridToggle();
1400 int onToggleHighQualityScreenRendering();
1401 enum
1402 {
1403 MENUID_VIEW_WALKABILITY,
1404 MENUID_VIEW_FLAGS,
1405 MENUID_VIEW_CSET,
1406 MENUID_VIEW_TYPES,
1407 MENUID_VIEW_INFO,
1408 MENUID_VIEW_SQUARES,
1409 MENUID_VIEW_FFCS,
1410 MENUID_VIEW_SCRIPTNAMES,
1411 MENUID_VIEW_GRID,
1412 MENUID_VIEW_SCREENGRID,
1413 MENUID_VIEW_REGIONGRID,
1414 MENUID_VIEW_CURSCROUTLINE,
1415 MENUID_VIEW_DARKNESS,
1416 MENUID_VIEW_L2BG,
1417 MENUID_VIEW_L3BG,
1418 MENUID_VIEW_LAYERHIGHLIGHT,
1419 MENUID_VIEW_HIGH_QUALITY_SCREEN_RENDERING,
1420 };
1421
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 NewMenu view_menu
1422 264 {
1423
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "View &Map...", onViewMap },
1424
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "View &Palette", onShowPal },
1425
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1426
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Walkability", onShowWalkability, MENUID_VIEW_WALKABILITY },
1427
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Flags", onShowFlags, MENUID_VIEW_FLAGS },
1428
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &CSets", onShowCSet, MENUID_VIEW_CSET },
1429
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Types", onShowCType, MENUID_VIEW_TYPES },
1430
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1431
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Screen &Info", onToggleShowInfo, MENUID_VIEW_INFO },
1432
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Squares", onToggleShowSquares, MENUID_VIEW_SQUARES },
1433
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show FFCs", onToggleShowFFCs, MENUID_VIEW_FFCS },
1434
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Script &Names", onToggleShowScripts, MENUID_VIEW_SCRIPTNAMES },
1435
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Grid", onGridToggle, MENUID_VIEW_GRID },
1436
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Screen G&rid", onToggleScreenGrid, MENUID_VIEW_SCREENGRID },
1437
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Region Grid", onToggleRegionGrid, MENUID_VIEW_REGIONGRID },
1438
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show Current Screen Outline", onToggleCurrentScreenOutline, MENUID_VIEW_CURSCROUTLINE },
1439
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Show &Darkness", onShowDarkness, MENUID_VIEW_DARKNESS },
1440
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Layer 2 is Background", onLayer2BG, MENUID_VIEW_L2BG },
1441
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Layer 3 is Background", onLayer3BG, MENUID_VIEW_L3BG },
1442
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Highlight Current Layer", onToggleHighlightLayer, MENUID_VIEW_LAYERHIGHLIGHT },
1443
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "High &Quality Screen Rendering", onToggleHighQualityScreenRendering, MENUID_VIEW_HIGH_QUALITY_SCREEN_RENDERING },
1444 };
1445
1446 11 void set_rules(byte* newrules)
1447 {
1448 11 mark_save_dirty();
1449
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(newrules != quest_rules)
1450 memcpy(quest_rules, newrules, QR_SZ);
1451 11 unpack_qrs();
1452
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 if(!get_qr(qr_ALLOW_EDITING_COMBO_0))
1453 {
1454 2 combobuf[0].walk = 0xF0;
1455 2 combobuf[0].type = 0;
1456 2 combobuf[0].flag = 0;
1457 2 }
1458
1459 // For 2.50.0 and 2.50.1
1460
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 if(get_qr(qr_VERYFASTSCROLLING))
1461 2 set_qr(qr_FASTDNGN, 1);
1462 11 }
1463
1464 int32_t onSelectFFCombo();
1465
1466 void onScreenNotes()
1467 {
1468 edit_screen_notes(Map.CurrScr(), Map.getCurrMap(), Map.getCurrScr());
1469 }
1470
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu data_menu
1471 216 {
1472
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Screen Data", onScrData },
1473
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Freeform Combos", onSelectFFCombo },
1474
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "La&yers", onLayers },
1475
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tile Warp", onTileWarp },
1476
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Side &Warp", onSideWarp },
1477
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Secret &Combos", onSecretCombo },
1478
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Under Combo", onUnderCombo },
1479
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Doors", onDoors },
1480
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Maze Path", onPath },
1481
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1482
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Item", onItem },
1483
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Enemies", onEnemies },
1484
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Palette", onScreenPalette },
1485
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1486
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Room Data", onRoom },
1487
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Notes", onScreenNotes },
1488
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Browse Notes", browse_screen_notes },
1489 };
1490
1491
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu tunes_menu
1492 252 {
1493
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "ZC Forever", playZCForever },
1494
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Wind Fish", playTune1 },
1495
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Overworld", playTune2 },
1496
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Hyrule Castle", playTune3 },
1497
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Lost Woods", playTune4 },
1498
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Great Sea", playTune5 },
1499
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "East Hyrule", playTune6 },
1500
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Dancing Dragon", playTune7 },
1501
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Stone Tower", playTune8 },
1502
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Villages", playTune9 },
1503
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Swamp + Desert", playTune10 },
1504
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Outset Island", playTune11 },
1505
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Kakariko Village", playTune12 },
1506
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Clock Town", playTune13 },
1507
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Temple", playTune14 },
1508
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Dark World", playTune15 },
1509
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Dragon Roost", playTune16 },
1510
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Horse Race", playTune17 },
1511
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Credits", playTune18 },
1512
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Zelda's Lullaby", playTune19 },
1513 };
1514
1515 enum
1516 {
1517 MENUID_MEDIA_TUNES,
1518 MENUID_MEDIA_PLAYMUSIC,
1519 MENUID_MEDIA_CHANGETRACK,
1520 };
1521
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu media_menu
1522 60 {
1523
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Ambient Music ", &tunes_menu, MENUID_MEDIA_TUNES },
1524
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Play music", playMusic, MENUID_MEDIA_PLAYMUSIC },
1525
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Change track", changeTrack, MENUID_MEDIA_CHANGETRACK },
1526
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Stop tunes", stopMusic },
1527 };
1528
1529 enum
1530 {
1531 MENUID_ETC_VIDMODE,
1532 MENUID_ETC_FULLSCREEN,
1533 MENUID_ETC_DEBUG_CONSOLE,
1534 };
1535
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu etc_menu
1536 192 {
1537
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Help", &zq_help_menu },
1538
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&About", onAbout },
1539
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Video Mode", onZQVidMode, MENUID_ETC_VIDMODE },
1540
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Options...", onOptions },
1541
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Hotkeys...", do_zq_hotkey_dialog },
1542
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&List Hotkeys...", do_zq_list_hotkeys_dialog },
1543
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Fullscreen", onFullScreen, MENUID_ETC_FULLSCREEN },
1544
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1545
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&View Pic...", onViewPic },
1546
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Media", &media_menu },
1547
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1548
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Debug Console", toggleConsole, MENUID_ETC_DEBUG_CONSOLE },
1549
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Clear Quest Filepath", onClearQuestFilepath },
1550
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Take ZQ Snapshot", onMenuSnapshot },
1551
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Take &Screen Snapshot", onMapscrSnapshot },
1552 };
1553
1554
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu zscript_menu
1555 60 {
1556
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Compile &ZScript...", onCompileScript },
1557
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 {},
1558
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Compiler Settings", onZScriptCompilerSettings },
1559
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Quest Script Settings", onZScriptSettings },
1560 };
1561
1562 void set_console_state()
1563 {
1564 etc_menu.select_uid(MENUID_ETC_DEBUG_CONSOLE, console_is_open);
1565 }
1566
1567
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 TopMenu the_menu
1568 108 {
1569
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&File", &file_menu },
1570
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Quest", &quest_menu },
1571
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Edit", &edit_menu },
1572
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&View", &view_menu },
1573
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Tools", &tool_menu },
1574
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&Screen", &data_menu },
1575
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "&ZScript", &zscript_menu },
1576
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Et&C", &etc_menu },
1577 };
1578
1579 void rebuild_trans_table();
1580 int32_t launchPicViewer(BITMAP **pictoview, PALETTE pal,
1581 int32_t &px2, int32_t &py2, double &scale, bool isviewingmap, bool skipmenu = false);
1582
1583 int32_t onResetTransparency()
1584 {
1585 restore_mouse();
1586 rebuild_trans_table();
1587 displayinfo("Notice","Translucency Table Rebuilt");
1588
1589 refresh(rALL);
1590 return D_O_K;
1591 }
1592
1593 int32_t onFullScreen()
1594 {
1595 get_palette(RAMpal);
1596 bool windowed=is_windowed_mode()!=0;
1597 all_toggle_fullscreen(windowed);
1598
1599 gui_mouse_focus=0;
1600 gui_bg_color=jwin_pal[jcBOX];
1601 gui_fg_color=jwin_pal[jcBOXFG];
1602 MouseSprite::set(ZQM_NORMAL);
1603 zc_set_palette(RAMpal);
1604 position_mouse(zq_screen_w/2,zq_screen_h/2);
1605 set_display_switch_mode(SWITCH_BACKGROUND);
1606 set_display_switch_callback(SWITCH_OUT, switch_out);
1607 set_display_switch_callback(SWITCH_IN, switch_in);
1608 zc_set_config("zquest","fullscreen", is_windowed_mode() ? 0 : 1);
1609 return D_REDRAW;
1610 }
1611
1612 int32_t onEnter()
1613 {
1614 if(key[KEY_ALT]||key[KEY_ALTGR])
1615 {
1616 return onFullScreen();
1617 }
1618
1619 return D_O_K;
1620 }
1621
1622 //PROC, x, y, w, h, fg, bg, key, flags, d1, d2, *dp, *dp2, *dp3
1623
1624 //*text, (*proc), *child, flags, *dp
1625
1626 void run_zq_frame();
1627 int32_t d_nbmenu_proc(int32_t msg,DIALOG *d,int32_t c);
1628
1629
1630 /*int32_t onY()
1631 {
1632 return D_O_K;
1633 }*/
1634
1635 int32_t onToggleGrid(bool color)
1636 {
1637 if(color)
1638 {
1639 GridColor=(GridColor+8)%16;
1640 zc_set_config("zquest", "grid_color", GridColor);
1641 }
1642 else
1643 {
1644 ShowGrid=!ShowGrid;
1645 zc_set_config("zquest","show_grid",ShowGrid);
1646 }
1647
1648 return D_O_K;
1649 }
1650
1651 int onGridToggle()
1652 {
1653 return onToggleGrid(CHECK_CTRL_CMD);
1654 }
1655
1656 int onToggleHighQualityScreenRendering()
1657 {
1658 HighQualityScreenRendering = !HighQualityScreenRendering;
1659 zc_set_config("zquest","high_quality_screen_rendering",HighQualityScreenRendering);
1660
1661 if (!HighQualityScreenRendering)
1662 {
1663 mapview_get_rti()->remove();
1664 }
1665
1666 return D_O_K;
1667 }
1668
1669 int32_t onToggleScreenGrid()
1670 {
1671 ShowScreenGrid=!ShowScreenGrid;
1672 zc_set_config("zquest","show_screen_grid",ShowScreenGrid);
1673 return D_O_K;
1674 }
1675
1676 int32_t onToggleRegionGrid()
1677 {
1678 ShowRegionGrid=!ShowRegionGrid;
1679 zc_set_config("zquest","show_region_grid",ShowRegionGrid);
1680 return D_O_K;
1681 }
1682
1683 int32_t onToggleCurrentScreenOutline()
1684 {
1685 ShowCurScreenOutline=!ShowCurScreenOutline;
1686 zc_set_config("zquest","show_current_screen_outline",ShowCurScreenOutline);
1687 return D_O_K;
1688 }
1689
1690 int32_t onToggleShowScripts()
1691 {
1692 ShowFFScripts=!ShowFFScripts;
1693 zc_set_config("zquest","showffscripts",ShowFFScripts);
1694 return D_O_K;
1695 }
1696
1697 int32_t onToggleShowFFCs()
1698 {
1699 ShowFFCs=!ShowFFCs;
1700 zc_set_config("zquest","showffcs",ShowFFCs);
1701 return D_O_K;
1702 }
1703
1704 int32_t onToggleShowSquares()
1705 {
1706 ShowSquares=!ShowSquares;
1707 zc_set_config("zquest","showsquares",ShowSquares);
1708 return D_O_K;
1709 }
1710
1711 int32_t onToggleShowInfo()
1712 {
1713 ShowInfo=!ShowInfo;
1714 zc_set_config("zquest","showinfo",ShowInfo);
1715 return D_O_K;
1716 }
1717
1718 int32_t onToggleHighlightLayer()
1719 {
1720 ActiveLayerHighlight = ActiveLayerHighlight ? 0 : 1;
1721 zc_set_config("zquest","hl_active_lyr",ActiveLayerHighlight);
1722 return D_O_K;
1723 }
1724
1725 int onKeySlash()
1726 {
1727 if(key[KEY_LSHIFT] || key[KEY_RSHIFT])
1728 {
1729 onAbout();
1730 }
1731 return D_O_K;
1732 }
1733
1734 int onAKey()
1735 {
1736 if(prv_mode)
1737 Map.set_prvadvance(1);
1738 return D_O_K;
1739 }
1740
1741 int onReloadPreview()
1742 {
1743 if(prv_mode)
1744 {
1745 Map.set_prvscr(Map.get_prv_map(), Map.get_prv_scr());
1746 Map.set_prvcmb(0);
1747 }
1748 return D_O_K;
1749 }
1750 int onSecretsPreview()
1751 {
1752 if(prv_mode)
1753 {
1754 Map.prv_secrets(false);
1755 refresh(rALL);
1756 }
1757 return D_O_K;
1758 }
1759
1760 int onSKey()
1761 {
1762 if(CHECK_CTRL_CMD)
1763 {
1764 if(key[KEY_LSHIFT] || key[KEY_RSHIFT])
1765 {
1766 onSaveAs();
1767 }
1768 else
1769 {
1770 if(!saved)
1771 onSave();
1772 }
1773 }
1774 else if(prv_mode)
1775 {
1776 Map.prv_secrets(false);
1777 refresh(rALL);
1778 }
1779 else onStrings();
1780 return D_O_K;
1781 }
1782 int onSetNewLayer(int newlayer)
1783 {
1784 CurrentLayer = newlayer;
1785 refresh(rALL);
1786 return D_O_K;
1787 }
1788 void lpal_dsa()
1789 {
1790 info_dsa("Level Palette Shortcuts",
1791 "You currently have level palette shortcuts disabled."
1792 " These can be re-enabled in 'Etc->Options', on the toggle 'Disable Level Palette Shortcuts'.",
1793 "dsa_lpal");
1794 }
1795 int onScreenLPal(int lpal)
1796 {
1797 if(DisableLPalShortcuts)
1798 {
1799 lpal_dsa();
1800 return D_O_K;
1801 }
1802 mark_save_dirty();
1803 Map.setcolor(lpal);
1804 refresh(rSCRMAP);
1805 return D_O_K;
1806 }
1807
1808 int32_t onPressEsc()
1809 {
1810 if(zoomed_minimap)
1811 mmap_set_zoom(false);
1812 else return onExit();
1813 return D_O_K;
1814 }
1815
1816 static DIALOG dialogs[] =
1817 {
1818 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
1819 { d_nbmenu_proc, 0, 0, 0, 13, 0, 0, 0, D_USER, 0, 0, (void *) &the_menu, NULL, NULL },
1820 { d_zq_hotkey_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
1821
1822 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *) onHelp, NULL, NULL },
1823 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_ESC, 0, (void *) onPressEsc, NULL, NULL },
1824 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, (void *) onUsedCombos, NULL, NULL },
1825 { d_vsync_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
1826 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
1827 };
1828
1829
1830 int32_t onDecColour()
1831 {
1832 if ( CHECK_CTRL_CMD )
1833 {
1834 return onDecScrPal16();
1835 }
1836
1837 else if ( key[KEY_LSHIFT] || key[KEY_RSHIFT] )
1838 {
1839 return onDecScrPal();
1840 }
1841
1842 else
1843 {
1844 return onDecreaseCSet();
1845 }
1846 }
1847
1848 int32_t onIncColour()
1849 {
1850
1851 if ( CHECK_CTRL_CMD )
1852 {
1853 return onIncScrPal16();
1854 }
1855
1856 else if ( key[KEY_LSHIFT] || key[KEY_RSHIFT] )
1857 {
1858 return onIncScrPal();
1859 }
1860
1861 else
1862 {
1863 return onIncreaseCSet();
1864 }
1865 }
1866
1867 static DIALOG save_tiles_dlg[] =
1868 {
1869 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
1870
1871
1872 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save Tile Pack", NULL, NULL },
1873 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
1874 //for future tabs
1875 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
1876 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
1877 //4
1878 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
1879 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
1880 //6
1881 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
1882 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
1883 //8
1884 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
1885 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
1886 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
1887 };
1888
1889
1890 void savesometiles(const char *prompt,int32_t initialval)
1891 {
1892
1893 char firsttile[8], tilecount[8];
1894 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
1895 sprintf(firsttile,"%d",0);
1896 sprintf(tilecount,"%d",1);
1897 //int32_t ret;
1898
1899
1900
1901 save_tiles_dlg[0].dp2 = get_zc_font(font_lfont);
1902
1903 sprintf(firsttile,"%d",0);
1904 sprintf(tilecount,"%d",1);
1905
1906 save_tiles_dlg[5].dp = firsttile;
1907 save_tiles_dlg[7].dp = tilecount;
1908
1909 large_dialog(save_tiles_dlg);
1910
1911 int32_t ret = do_zqdialog(save_tiles_dlg,-1);
1912 jwin_center_dialog(save_tiles_dlg);
1913
1914 if(ret == 8)
1915 {
1916 first_tile_id = vbound(atoi(firsttile), 0, NEWMAXTILES);
1917 the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
1918 if(prompt_for_new_file_compat("Save ZTILE(.ztile)", "ztile", NULL,datapath,false))
1919 {
1920 char name[PATH_MAX];
1921 extract_name(temppath,name,FILENAMEALL);
1922 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
1923 if(f)
1924 {
1925 writetilefile(f,first_tile_id,the_tile_count);
1926 pack_fclose(f);
1927 displayinfo("Success!",fmt::format("Saved {}",name));
1928 }
1929 }
1930 }
1931 }
1932
1933 static DIALOG read_tiles_dlg[] =
1934 {
1935 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
1936
1937
1938 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Load Tilepack To:", NULL, NULL },
1939 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
1940 //for future tabs
1941 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
1942 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
1943 //4
1944 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Starting at:", NULL, NULL },
1945 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
1946 //6
1947 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
1948 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
1949 //8
1950 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
1951 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
1952 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
1953 };
1954
1955
1956 void writesometiles_to(const char *prompt,int32_t initialval)
1957 {
1958
1959 char firsttile[8];;
1960 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
1961 sprintf(firsttile,"%d",0);
1962 //int32_t ret;
1963
1964
1965
1966 read_tiles_dlg[0].dp2 = get_zc_font(font_lfont);
1967
1968 sprintf(firsttile,"%d",0);
1969 //sprintf(tilecount,"%d",1);
1970
1971 read_tiles_dlg[5].dp = firsttile;
1972
1973 large_dialog(read_tiles_dlg);
1974
1975 int32_t ret = do_zqdialog(read_tiles_dlg,-1);
1976 jwin_center_dialog(read_tiles_dlg);
1977
1978 if(ret == 8)
1979 {
1980 first_tile_id = vbound(atoi(firsttile), 0, NEWMAXTILES);
1981 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
1982 if(prompt_for_existing_file_compat("Load ZTILE(.ztile)", "ztile", NULL,datapath,false))
1983 {
1984
1985 char name[256];
1986 extract_name(temppath,name,FILENAMEALL);
1987 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
1988 if(f)
1989 {
1990
1991 if (!readtilefile_to_location(f,first_tile_id))
1992 {
1993 al_trace("Could not read from .ztile packfile %s\n", name);
1994 displayinfo("ZTILE File: Error","Could not load the specified Tile.");
1995 }
1996 else
1997 {
1998 displayinfo("ZTILE File: Success!","Loaded the source tiles to your tile sheets!");
1999 }
2000 pack_fclose(f);
2001 }
2002 }
2003 }
2004 }
2005
2006
2007 static DIALOG save_combofiles_dlg[] =
2008 {
2009 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2010
2011
2012 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save Combo Pack", NULL, NULL },
2013 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2014 //for future tabs
2015 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2016 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2017 //4
2018 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
2019 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2020 //6
2021 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2022 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2023 //8
2024 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
2025 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2026 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2027 };
2028
2029
2030 void savesomecombos(const char *prompt,int32_t initialval)
2031 {
2032
2033 char firsttile[8], tilecount[8];
2034 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2035 sprintf(firsttile,"%d",0);
2036 sprintf(tilecount,"%d",1);
2037 //int32_t ret;
2038
2039
2040
2041 save_combofiles_dlg[0].dp2 = get_zc_font(font_lfont);
2042
2043 sprintf(firsttile,"%d",0);
2044 sprintf(tilecount,"%d",1);
2045
2046 save_combofiles_dlg[5].dp = firsttile;
2047 save_combofiles_dlg[7].dp = tilecount;
2048
2049 large_dialog(save_combofiles_dlg);
2050
2051 int32_t ret = do_zqdialog(save_combofiles_dlg,-1);
2052 jwin_center_dialog(save_combofiles_dlg);
2053
2054 if(ret == 8)
2055 {
2056 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOS-1));
2057 the_tile_count = vbound(atoi(tilecount), 1, (MAXCOMBOS-1)-first_tile_id);
2058 if(prompt_for_new_file_compat("Save ZCOMBO(.zcombo)", "zcombo", NULL,datapath,false))
2059 {
2060 char name[PATH_MAX];
2061 extract_name(temppath,name,FILENAMEALL);
2062 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
2063 if(f)
2064 {
2065 writecombofile(f,first_tile_id,the_tile_count);
2066 pack_fclose(f);
2067 displayinfo("Success!",fmt::format("Saved {}",name));
2068 }
2069 }
2070 }
2071 }
2072
2073
2074 static DIALOG load_comboset_dlg[] =
2075 {
2076 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2077
2078
2079 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Combo Set (Range)", NULL, NULL },
2080 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2081 //for future tabs
2082 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2083 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2084 //4
2085 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First:", NULL, NULL },
2086 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2087 //6
2088 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2089 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2090 //8
2091 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2092 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2093 { jwin_check_proc, 10, 46, 95, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Don't Overwrite", NULL, NULL },
2094
2095 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2096 };
2097
2098 void writesomecombos(const char *prompt,int32_t initialval)
2099 {
2100
2101 char firsttile[8];
2102 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2103 sprintf(firsttile,"%d",0);
2104 //int32_t ret;
2105
2106
2107
2108 load_comboset_dlg[0].dp2 = get_zc_font(font_lfont);
2109
2110 sprintf(firsttile,"%d",0);
2111 //sprintf(tilecount,"%d",1);
2112
2113 load_comboset_dlg[5].dp = firsttile;
2114
2115 byte nooverwrite = 0;
2116
2117
2118 large_dialog(load_comboset_dlg);
2119
2120 int32_t ret = do_zqdialog(load_comboset_dlg,-1);
2121 jwin_center_dialog(load_comboset_dlg);
2122
2123 if(ret == 8)
2124 {
2125 if (load_comboset_dlg[10].flags & D_SELECTED) nooverwrite = 1;
2126
2127 al_trace("Nooverwrite is: %d\n", nooverwrite);
2128 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOS-1));
2129 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
2130 if(prompt_for_existing_file_compat("Load ZCOMBO(.zcombo)", "zcombo", NULL,datapath,false))
2131 {
2132 char name[256];
2133 extract_name(temppath,name,FILENAMEALL);
2134 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2135 if(f)
2136 {
2137
2138 if (!readcombofile(f,first_tile_id,nooverwrite))
2139 {
2140 al_trace("Could not read from .zcombo packfile %s\n", name);
2141 displayinfo("ZCOMBO File: Error","Could not load the specified combos.");
2142 }
2143 else
2144 {
2145 displayinfo("ZCOMBO File: Success!","Loaded the source combos to your combo pages!");
2146 mark_save_dirty();
2147 }
2148 pack_fclose(f);
2149 }
2150
2151 }
2152 }
2153 }
2154
2155 static DIALOG load_combopack_dlg[] =
2156 {
2157 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2158
2159
2160 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Import Full Combo Package 1:1", NULL, NULL },
2161 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2162 //for future tabs
2163 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2164 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2165 //4
2166 { d_dummy_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Starting at:", NULL, NULL },
2167 { d_dummy_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2168 //6
2169 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2170 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2171 //8
2172 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2173 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2174 { jwin_check_proc, 10, 42, 95, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Don't Overwrite", NULL, NULL },
2175
2176 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2177 };
2178
2179 void loadcombopack(const char *prompt,int32_t initialval)
2180 {
2181
2182 char firsttile[8];
2183 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2184 sprintf(firsttile,"%d",0);
2185 //int32_t ret;
2186
2187
2188
2189 load_combopack_dlg[0].dp2 = get_zc_font(font_lfont);
2190
2191 sprintf(firsttile,"%d",0);
2192 //sprintf(tilecount,"%d",1);
2193
2194 load_combopack_dlg[5].dp = firsttile;
2195
2196 byte nooverwrite = 0;
2197
2198
2199 large_dialog(load_combopack_dlg);
2200
2201 int32_t ret = do_zqdialog(load_combopack_dlg,-1);
2202 jwin_center_dialog(load_combopack_dlg);
2203
2204 if(ret == 8)
2205 {
2206 if (load_combopack_dlg[10].flags & D_SELECTED) nooverwrite = 1;
2207
2208 al_trace("Nooverwrite is: %d\n", nooverwrite);
2209 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOS-1));
2210 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
2211 if(prompt_for_existing_file_compat("Load ZCOMBO(.zcombo)", "zcombo", NULL,datapath,false))
2212 {
2213 char name[256];
2214 extract_name(temppath,name,FILENAMEALL);
2215 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2216 if(f)
2217 {
2218 //need dialogue here
2219 if (!readcombofile(f,0,nooverwrite))
2220 {
2221 al_trace("Could not read from .zcombo packfile %s\n", name);
2222 displayinfo("ZCOMBO File: Error","Could not load the specified Tile.");
2223 }
2224 else
2225 {
2226 displayinfo("ZCOMBO File: Success!","Loaded the source combos to your combo pages!");
2227 mark_save_dirty();
2228 }
2229 }
2230
2231 pack_fclose(f);
2232 }
2233 }
2234 }
2235
2236
2237 static DIALOG read_combopack_dlg[] =
2238 {
2239 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2240
2241
2242 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Load Combos (Specific Dest)", NULL, NULL },
2243 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2244 //for future tabs
2245 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2246 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2247 //4
2248 { jwin_text_proc, 10, 24, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Starting at:", NULL, NULL },
2249 { jwin_edit_proc, 55, 22, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2250 //6
2251 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2252 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2253 //8
2254 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2255 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2256 //10
2257 { jwin_check_proc, 10, 58, 95, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Don't Overwrite", NULL, NULL },
2258 //11
2259 { jwin_text_proc, 10, 42, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Skip:", NULL, NULL },
2260 //12
2261 { jwin_edit_proc, 55, 40, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2262
2263 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2264 };
2265
2266
2267
2268 void writesomecombos_to(const char *prompt,int32_t initialval)
2269 {
2270
2271 char firsttile[8];
2272 char skiptile[8];
2273 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2274 sprintf(firsttile,"%d",0);
2275 //int32_t ret;
2276
2277
2278
2279 read_combopack_dlg[0].dp2 = get_zc_font(font_lfont);
2280
2281 sprintf(skiptile,"%d",0);
2282 //sprintf(tilecount,"%d",1);
2283
2284 read_combopack_dlg[5].dp = firsttile;
2285
2286 byte nooverwrite = 0;
2287 int32_t skipover = 0;
2288
2289 sprintf(skiptile,"%d",0);
2290 //sprintf(tilecount,"%d",1);
2291
2292 read_combopack_dlg[12].dp = skiptile;
2293
2294 large_dialog(read_combopack_dlg);
2295
2296 int32_t ret = do_zqdialog(read_combopack_dlg,-1);
2297 jwin_center_dialog(read_combopack_dlg);
2298
2299 if(ret == 8)
2300 {
2301 if (read_combopack_dlg[10].flags & D_SELECTED) nooverwrite = 1;
2302
2303 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOS-1));
2304 skipover = vbound(atoi(skiptile), 0, (MAXCOMBOS-1));
2305 al_trace("skipover is: %d\n", skipover);
2306 //skipover = vbound(skipover, 0, (MAXCOMBOS-1-skipover));
2307 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
2308 if(prompt_for_existing_file_compat("Load ZCOMBO(.zcombo)", "zcombo", NULL,datapath,false))
2309 {
2310 char name[256];
2311 extract_name(temppath,name,FILENAMEALL);
2312 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2313 if(f)
2314 {
2315
2316 if (!readcombofile_to_location(f,first_tile_id,nooverwrite, skipover))
2317 {
2318 al_trace("Could not read from .zcombo packfile %s\n", name);
2319 displayinfo("ZCOMBO File: Error","Could not load the specified combos.");
2320 }
2321 else
2322 {
2323 displayinfo("ZCOMBO File: Success!","Loaded the source combos to your combo pages!");
2324 mark_save_dirty();
2325 }
2326 pack_fclose(f);
2327 }
2328
2329 }
2330 }
2331 }
2332
2333
2334
2335 static DIALOG save_dmaps_dlg[] =
2336 {
2337 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2338
2339
2340 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save DMaps (.zdmap)", NULL, NULL },
2341 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2342 //for future tabs
2343 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2344 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2345 //4
2346 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
2347 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2348 //6
2349 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Last", NULL, NULL },
2350 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2351 //8
2352 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
2353 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2354 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2355 };
2356
2357
2358 void savesomedmaps(const char *prompt,int32_t initialval)
2359 {
2360
2361 char firstdmap[8], lastdmap[8];
2362 int32_t first_dmap_id = 0; int32_t last_dmap_id = 0;
2363 sprintf(firstdmap,"%d",0);
2364 sprintf(lastdmap,"%d",1);
2365 //int32_t ret;
2366
2367
2368
2369 save_dmaps_dlg[0].dp2 = get_zc_font(font_lfont);
2370
2371 sprintf(firstdmap,"%d",0);
2372 sprintf(lastdmap,"%d",0);
2373
2374 save_dmaps_dlg[5].dp = firstdmap;
2375 save_dmaps_dlg[7].dp = lastdmap;
2376
2377 large_dialog(save_dmaps_dlg);
2378
2379 int32_t ret = do_zqdialog(save_dmaps_dlg,-1);
2380 jwin_center_dialog(save_dmaps_dlg);
2381
2382 if(ret == 8)
2383 {
2384 first_dmap_id = vbound(atoi(firstdmap), 0, MAXDMAPS-1);
2385 last_dmap_id = vbound(atoi(lastdmap), 0, MAXDMAPS-1);
2386
2387 if ( last_dmap_id < first_dmap_id )
2388 {
2389 int32_t swap = last_dmap_id;
2390 last_dmap_id = first_dmap_id;
2391 first_dmap_id = swap;
2392 }
2393 if(!prompt_for_new_file_compat("Export DMaps (.zdmap)","zdmap",NULL,datapath,false))
2394
2395
2396 mark_save_dirty();
2397
2398 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
2399 if(f)
2400 {
2401 if(!writesomedmaps(f,first_dmap_id,last_dmap_id,MAXDMAPS))
2402 {
2403 char name[PATH_MAX];
2404 extract_name(temppath,name,FILENAMEALL);
2405 displayinfo("Error",fmt::format("Unable to load {}",name));
2406 }
2407 else
2408 {
2409 char name[PATH_MAX];
2410 extract_name(temppath,name,FILENAMEALL);
2411 displayinfo("Success!",fmt::format("Saved {}",name));
2412 }
2413 }
2414 pack_fclose(f);
2415 }
2416 }
2417
2418 static DIALOG save_comboaliasfiles_dlg[] =
2419 {
2420 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2421
2422
2423 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save Combo Alias Pack", NULL, NULL },
2424 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2425 //for future tabs
2426 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2427 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2428 //4
2429 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
2430 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2431 //6
2432 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2433 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2434 //8
2435 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
2436 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2437 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2438 };
2439
2440
2441 void savesomecomboaliases(const char *prompt,int32_t initialval)
2442 {
2443
2444 char firsttile[8], tilecount[8];
2445 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2446 sprintf(firsttile,"%d",0);
2447 sprintf(tilecount,"%d",1);
2448 //int32_t ret;
2449
2450
2451
2452 save_comboaliasfiles_dlg[0].dp2 = get_zc_font(font_lfont);
2453
2454 sprintf(firsttile,"%d",0);
2455 sprintf(tilecount,"%d",1);
2456
2457 save_comboaliasfiles_dlg[5].dp = firsttile;
2458 save_comboaliasfiles_dlg[7].dp = tilecount;
2459
2460 large_dialog(save_comboaliasfiles_dlg);
2461
2462 int32_t ret = do_zqdialog(save_comboaliasfiles_dlg,-1);
2463 jwin_center_dialog(save_comboaliasfiles_dlg);
2464
2465 if(ret == 8)
2466 {
2467 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOALIASES-1));
2468 the_tile_count = vbound(atoi(tilecount), 1, (MAXCOMBOALIASES-1)-first_tile_id);
2469 if(prompt_for_new_file_compat("Save ZALIAS(.zalias)", "zalias", NULL,datapath,false))
2470 {
2471 char name[PATH_MAX];
2472 extract_name(temppath,name,FILENAMEALL);
2473 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
2474 if(f)
2475 {
2476 writecomboaliasfile(f,first_tile_id,the_tile_count);
2477 pack_fclose(f);
2478 displayinfo("Success!",fmt::format("Saved {}",name));
2479 }
2480 }
2481 }
2482 }
2483
2484
2485 static DIALOG read_comboaliaspack_dlg[] =
2486 {
2487 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2488
2489
2490 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Load Combo Pack To:", NULL, NULL },
2491 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2492 //for future tabs
2493 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2494 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2495 //4
2496 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Starting at:", NULL, NULL },
2497 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2498 //6
2499 { d_dummy_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2500 { d_dummy_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2501 //8
2502 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2503 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2504 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2505 };
2506
2507
2508 void writesomecomboaliases_to(const char *prompt,int32_t initialval)
2509 {
2510
2511 char firsttile[8];;
2512 int32_t first_tile_id = 0; int32_t the_tile_count = 1;
2513 sprintf(firsttile,"%d",0);
2514 //int32_t ret;
2515
2516
2517
2518 read_comboaliaspack_dlg[0].dp2 = get_zc_font(font_lfont);
2519
2520 sprintf(firsttile,"%d",0);
2521 //sprintf(tilecount,"%d",1);
2522
2523 read_comboaliaspack_dlg[5].dp = firsttile;
2524
2525 large_dialog(read_comboaliaspack_dlg);
2526
2527 int32_t ret = do_zqdialog(read_comboaliaspack_dlg,-1);
2528 jwin_center_dialog(read_comboaliaspack_dlg);
2529
2530 if(ret == 8)
2531 {
2532 first_tile_id = vbound(atoi(firsttile), 0, (MAXCOMBOALIASES-1));
2533 //the_tile_count = vbound(atoi(tilecount), 1, NEWMAXTILES-first_tile_id);
2534 if(prompt_for_existing_file_compat("Load ZALIAS(.zalias)", "zalias", NULL,datapath,false))
2535 {
2536 char name[256];
2537 extract_name(temppath,name,FILENAMEALL);
2538 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2539 if(f)
2540 {
2541
2542 if (!readcomboaliasfile_to_location(f,first_tile_id))
2543 {
2544 al_trace("Could not read from .zcombo packfile %s\n", name);
2545 displayinfo("ZALIAS File: Error","Could not load the specified combo aliases.");
2546 }
2547 else
2548 {
2549 displayinfo("ZALIAS File: Success!","Loaded the source combos to your combo alias table!");
2550 mark_save_dirty();
2551 }
2552 pack_fclose(f);
2553 }
2554 }
2555 }
2556 }
2557
2558
2559
2560
2561 //Doorsets
2562
2563 static DIALOG save_doorset_dlg[] =
2564 {
2565 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2566 { jwin_win_proc, 0, 0, 120, 100, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Save Doorset", NULL, NULL },
2567 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2568 //for future tabs
2569 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2570 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2571 //4
2572 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First", NULL, NULL },
2573 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2574 //6
2575 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2576 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2577 //8
2578 { jwin_button_proc, 15, 72, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Save", NULL, NULL },
2579 { jwin_button_proc, 69, 72, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2580 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2581 };
2582
2583
2584 void do_exportdoorset(const char *prompt,int32_t initialval)
2585 {
2586 char firstdoor[8], doorct[8];
2587 int32_t first_doorset_id = 0; int32_t the_doorset_count = 1;
2588 sprintf(firstdoor,"%d",0);
2589 sprintf(doorct,"%d",1);
2590 //int32_t ret;
2591 save_doorset_dlg[0].dp2 = get_zc_font(font_lfont);
2592
2593 sprintf(firstdoor,"%d",0);
2594 sprintf(doorct,"%d",1);
2595
2596 save_doorset_dlg[5].dp = firstdoor;
2597 save_doorset_dlg[7].dp = doorct;
2598
2599 large_dialog(save_doorset_dlg);
2600
2601 int32_t ret = do_zqdialog(save_doorset_dlg,-1);
2602 jwin_center_dialog(save_doorset_dlg);
2603
2604 if(ret == 8) //OK
2605 {
2606 /* sanity bounds
2607 first_doorset_id = vbound(atoi(firstdoor), 0, (MAXCOMBOS-1));
2608 the_doorset_count = vbound(atoi(doorct), 1, (MAXCOMBOS-1)-first_doorset_id);
2609 */
2610 if(prompt_for_new_file_compat("Save ZDOORS(.zdoors)", "zdoors", NULL,datapath,false))
2611 {
2612 char name[256];
2613 extract_name(temppath,name,FILENAMEALL);
2614 PACKFILE *f=pack_fopen_password(temppath,F_WRITE, "");
2615 if(f)
2616 {
2617 writezdoorsets(f,first_doorset_id,the_doorset_count);
2618 pack_fclose(f);
2619 displayinfo("Success!",fmt::format("Saved {}",name));
2620 }
2621 }
2622 }
2623 }
2624
2625 static DIALOG load_doorset_dlg[] =
2626 {
2627 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
2628 { jwin_win_proc, 0, 0, 120, 124, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Door Set (Range)", NULL, NULL },
2629 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
2630 //for future tabs
2631 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2632 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
2633 //4
2634 { jwin_text_proc, 10, 28, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "First:", NULL, NULL },
2635 { jwin_edit_proc, 55, 26, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2636 //6
2637 { jwin_text_proc, 10, 46, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Count", NULL, NULL },
2638 { jwin_edit_proc, 55, 44, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2639 //8
2640 { jwin_button_proc, 15, 92, 36, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Load", NULL, NULL },
2641 { jwin_button_proc, 69, 92, 36, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
2642 //10
2643 { jwin_text_proc, 10, 64, 20, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Dest", NULL, NULL },
2644 { jwin_edit_proc, 55, 63, 40, 16, vc(12), vc(1), 0, 0, 63, 0, NULL, NULL, NULL },
2645 //8
2646
2647 // { jwin_check_proc, 10, 46, 95, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Don't Overwrite", NULL, NULL },
2648
2649 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
2650 };
2651
2652 void do_importdoorset(const char *prompt,int32_t initialval)
2653 {
2654
2655 char firstdoor[8], doorct[8], destid[8];
2656 int32_t first_doorset_id = 0; int32_t the_doorset_count = 1;
2657 int32_t the_dest_id = 0;
2658 sprintf(firstdoor,"%d",0);
2659 sprintf(doorct,"%d",1);
2660 sprintf(destid,"%d",0);
2661 //int32_t ret;
2662
2663 save_doorset_dlg[0].dp2 = get_zc_font(font_lfont);
2664
2665 load_doorset_dlg[5].dp = firstdoor;
2666 load_doorset_dlg[7].dp = doorct;
2667 load_doorset_dlg[11].dp = destid;
2668
2669 byte nooverwrite = 0;
2670
2671 large_dialog(load_doorset_dlg);
2672
2673 int32_t ret = do_zqdialog(load_doorset_dlg,-1);
2674 jwin_center_dialog(load_doorset_dlg);
2675
2676 if(ret == 8) //OK
2677 {
2678 //if (load_doorset_dlg[10].flags & D_SELECTED) nooverwrite = 1;
2679
2680 //sanity bound
2681 first_doorset_id = vbound(atoi(firstdoor), 0, door_combo_set_count);
2682 the_doorset_count = vbound(atoi(doorct), 1, door_combo_set_count);
2683 the_dest_id = vbound(atoi(destid), 0, door_combo_set_count);
2684 if(prompt_for_existing_file_compat("Load ZDOORS(.zdoors)", "zdoors", NULL,datapath,false))
2685 {
2686 char name[256];
2687 extract_name(temppath,name,FILENAMEALL);
2688 PACKFILE *f=pack_fopen_password(temppath,F_READ, "");
2689 if(f)
2690 {
2691 int32_t ret = readzdoorsets(f,first_doorset_id,the_doorset_count, the_dest_id);
2692
2693 if (!ret)
2694 {
2695 al_trace("Could not read from .zdoors packfile %s\n", name);
2696 displayinfo("ZDOORS File: Error","Could not load the specified doorsets.");
2697 }
2698 else if ( ret == 1 )
2699 {
2700 displayinfo("ZDOORS File: Success!","Loaded the source doorsets!");
2701 mark_save_dirty();
2702 }
2703 else if ( ret == 2 )
2704 {
2705 displayinfo("ZDOORS File: Issue:","Targets exceed doorset count!");
2706 mark_save_dirty();
2707 }
2708 pack_fclose(f);
2709 }
2710 }
2711 }
2712 }
2713
2714 void update_combo_cycling()
2715 {
2716 Map.update_combo_cycling();
2717 }
2718
2719 void update_freeform_combos()
2720 {
2721 Map.update_freeform_combos();
2722 }
2723
2724 bool layers_valid(mapscr *tempscr)
2725 {
2726 for(int32_t i=0; i<6; i++)
2727 {
2728 if(tempscr->layermap[i]>map_count)
2729 {
2730 return false;
2731 }
2732 }
2733
2734 return true;
2735 }
2736
2737 void fix_layers(mapscr *tempscr, bool showwarning)
2738 {
2739 char buf[80]="";
2740
2741 for(int32_t i=0; i<6; i++)
2742 {
2743 if(tempscr->layermap[i]>map_count)
2744 {
2745 strcat(buf, "%d ");
2746 sprintf(buf, buf, i+1);
2747 tempscr->layermap[i]=0;
2748 }
2749 }
2750
2751 if(showwarning)
2752 {
2753 displayinfo("Invalid layers detected",
2754 fmt::format("One or more layers on this screen used"
2755 "maps that do not exist. The settings of these"
2756 "layers have been changed: {}", buf));
2757 }
2758 }
2759
2760 extern const char *colorlist(int32_t index, int32_t *list_size);
2761
2762 static char autobackup_str_buf[32];
2763 const char *autobackuplist(int32_t index, int32_t *list_size)
2764 {
2765 if(index>=0)
2766 {
2767 bound(index,0,10);
2768
2769 if(index==0)
2770 {
2771 sprintf(autobackup_str_buf,"Disabled");
2772 }
2773 else
2774 {
2775 sprintf(autobackup_str_buf,"%2d",index);
2776 }
2777
2778 return autobackup_str_buf;
2779 }
2780
2781 *list_size=11;
2782 return NULL;
2783 }
2784
2785 static char autosave_str_buf[32];
2786 const char *autosavelist(int32_t index, int32_t *list_size)
2787 {
2788 if(index>=0)
2789 {
2790 bound(index,0,10);
2791
2792 if(index==0)
2793 {
2794 sprintf(autosave_str_buf,"Disabled");
2795 }
2796 else
2797 {
2798 sprintf(autosave_str_buf,"%2d Minute%c",index,index>1?'s':0);
2799 }
2800
2801 return autosave_str_buf;
2802 }
2803
2804 *list_size=11;
2805 return NULL;
2806 }
2807
2808 const char *autosavelist2(int32_t index, int32_t *list_size)
2809 {
2810 if(index>=0)
2811 {
2812 bound(index,0,9);
2813 sprintf(autosave_str_buf,"%2d",index+1);
2814 return autosave_str_buf;
2815 }
2816
2817 *list_size=10;
2818 return NULL;
2819 }
2820
2821
2822 static int32_t options_1_list[] =
2823 {
2824 // dialog control number
2825 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1
2826 };
2827
2828 static int32_t options_2_list[] =
2829 {
2830 // dialog control number
2831 50, 51, -1
2832 };
2833
2834 static int32_t options_3_list[] =
2835 {
2836 // dialog control number
2837 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, -1
2838 };
2839 static int32_t options_4_list[] =
2840 {
2841 57, 58, 59, 60,
2842 -1
2843 };
2844
2845 static TABPANEL options_tabs[] =
2846 {
2847 // (text)
2848 { (char *)" 1 ", D_SELECTED, options_1_list, 0, NULL },
2849 { (char *)" 2 ", 0, options_2_list, 0, NULL },
2850 { (char *)" 3 ", 0, options_3_list, 0, NULL },
2851 { (char *)" 4 ", 0, options_4_list, 0, NULL },
2852 { NULL, 0, NULL, 0, NULL }
2853 };
2854
2855 12 static ListData autobackup_list(autobackuplist, &font);
2856 12 static ListData autosave_list(autosavelist, &font);
2857 12 static ListData autosave_list2(autosavelist2, &font);
2858 12 static ListData color_list(colorlist, &font);
2859 12 static ListData snapshotformat_list(snapshotformatlist, &font);
2860
2861 const char *dm_names[dm_max]=
2862 {
2863 "Normal",
2864 "Relational", // Removed.
2865 "Dungeon", // Removed.
2866 "Alias",
2867 "Pool",
2868 "Auto"
2869 };
2870
2871 void fix_drawing_mode_menu()
2872 {
2873 drawing_mode_menu.select_only_uid(draw_mode);
2874 }
2875
2876 int32_t onDrawingMode()
2877 {
2878 draw_mode=(draw_mode+1)%dm_max;
2879 int dm_relational = 1;
2880 if ((int)draw_mode == dm_relational)
2881 draw_mode += 2;
2882 fix_drawing_mode_menu();
2883 restore_mouse();
2884 return D_O_K;
2885 }
2886
2887 int32_t onDrawingModeNormal()
2888 {
2889 draw_mode=dm_normal;
2890 fix_drawing_mode_menu();
2891 restore_mouse();
2892 return D_O_K;
2893 }
2894
2895 int32_t onDrawingModeAlias()
2896 {
2897 if(draw_mode==dm_alias)
2898 {
2899 return onDrawingModeNormal();
2900 }
2901
2902 draw_mode=dm_alias;
2903 alias_cset_mod=0;
2904 fix_drawing_mode_menu();
2905 restore_mouse();
2906 return D_O_K;
2907 }
2908
2909 int32_t onDrawingModePool()
2910 {
2911 if(draw_mode==dm_cpool)
2912 {
2913 return onDrawingModeNormal();
2914 }
2915
2916 draw_mode=dm_cpool;
2917 fix_drawing_mode_menu();
2918 restore_mouse();
2919 return D_O_K;
2920 }
2921
2922 int32_t onDrawingModeAuto()
2923 {
2924 if (draw_mode == dm_auto)
2925 {
2926 return onDrawingModeNormal();
2927 }
2928
2929 draw_mode = dm_auto;
2930 fix_drawing_mode_menu();
2931 restore_mouse();
2932 return D_O_K;
2933 }
2934
2935 int32_t onReTemplate()
2936 {
2937 if (alert_confirm("Confirm Overwrite","Apply NES Dungeon template to all screens on this map?"))
2938 {
2939 Map.TemplateAll();
2940 refresh(rALL);
2941 }
2942
2943 return D_O_K;
2944 }
2945
2946 int32_t onUndo()
2947 {
2948 Map.UndoCommand();
2949 refresh(rALL);
2950 return D_O_K;
2951 }
2952
2953 int32_t onRedo()
2954 {
2955 Map.RedoCommand();
2956 refresh(rALL);
2957 return D_O_K;
2958 }
2959
2960 int32_t onCopy()
2961 {
2962 if(prv_mode)
2963 {
2964 Map.set_prvcmb(Map.get_prvcmb()==0?1:0);
2965 return D_O_K;
2966 }
2967
2968 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
2969 Map.Copy(screen);
2970 return D_O_K;
2971 }
2972
2973 int32_t onPaste()
2974 {
2975 if(key[KEY_LSHIFT] || key[KEY_RSHIFT])
2976 {
2977 if(CHECK_CTRL_CMD)
2978 return onPasteAllToAll();
2979 else return onPasteAll();
2980 }
2981 else if(CHECK_CTRL_CMD)
2982 return onPasteToAll();
2983 else
2984 {
2985 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
2986 Map.DoPasteScreenCommand(PasteCommandType::ScreenPartial, screen);
2987 }
2988 return D_O_K;
2989 }
2990
2991 int32_t onPasteAll()
2992 {
2993 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
2994 Map.DoPasteScreenCommand(PasteCommandType::ScreenAll, screen);
2995 return D_O_K;
2996 }
2997
2998 int32_t onPasteToAll()
2999 {
3000 if(alert_confirm("Confirmation", "You are about to paste to all screens on the current map.\nAre you sure?"))
3001 Map.DoPasteScreenCommand(PasteCommandType::ScreenPartialToEveryScreen);
3002 return D_O_K;
3003 }
3004
3005 int32_t onPasteAllToAll()
3006 {
3007 if(alert_confirm("Confirmation", "You are about to paste to all screens on the current map.\nAre you sure?"))
3008 Map.DoPasteScreenCommand(PasteCommandType::ScreenAllToEveryScreen);
3009 return D_O_K;
3010 }
3011
3012 int32_t onPasteUnderCombo()
3013 {
3014 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3015 Map.DoPasteScreenCommand(PasteCommandType::ScreenUnderCombo, screen);
3016 return D_O_K;
3017 }
3018
3019 int32_t onPasteSecretCombos()
3020 {
3021 Map.DoPasteScreenCommand(PasteCommandType::ScreenSecretCombos);
3022 return D_O_K;
3023 }
3024
3025 int32_t onPasteFFCombos()
3026 {
3027 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3028 Map.DoPasteScreenCommand(PasteCommandType::ScreenFFCombos, screen);
3029 return D_O_K;
3030 }
3031
3032 int32_t onPasteWarps()
3033 {
3034 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3035 Map.DoPasteScreenCommand(PasteCommandType::ScreenWarps, screen);
3036 return D_O_K;
3037 }
3038
3039 int32_t onPasteScreenData()
3040 {
3041 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3042 Map.DoPasteScreenCommand(PasteCommandType::ScreenData, screen);
3043 return D_O_K;
3044 }
3045
3046 int32_t onPasteWarpLocations()
3047 {
3048 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3049 Map.DoPasteScreenCommand(PasteCommandType::ScreenWarpLocations, screen);
3050 return D_O_K;
3051 }
3052
3053 int32_t onPasteDoors()
3054 {
3055 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3056 Map.DoPasteScreenCommand(PasteCommandType::ScreenDoors, screen);
3057 return D_O_K;
3058 }
3059
3060 int32_t onPasteLayers()
3061 {
3062 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3063 Map.DoPasteScreenCommand(PasteCommandType::ScreenLayers, screen);
3064 return D_O_K;
3065 }
3066
3067 int32_t onPastePalette()
3068 {
3069 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3070 Map.DoPasteScreenCommand(PasteCommandType::ScreenPalette, screen);
3071 return D_O_K;
3072 }
3073
3074 int32_t onPasteRoom()
3075 {
3076 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3077 Map.DoPasteScreenCommand(PasteCommandType::ScreenRoom, screen);
3078 return D_O_K;
3079 }
3080
3081 int32_t onPasteGuy()
3082 {
3083 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3084 Map.DoPasteScreenCommand(PasteCommandType::ScreenGuy, screen);
3085 return D_O_K;
3086 }
3087
3088 int32_t onPasteEnemies()
3089 {
3090 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3091 Map.DoPasteScreenCommand(PasteCommandType::ScreenEnemies, screen);
3092 return D_O_K;
3093 }
3094
3095 int32_t onDelete()
3096 {
3097 restore_mouse();
3098
3099 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
3100 mapscr* scr = active_visible_screen ? active_visible_screen->scr : Map.CurrScr();
3101 if(!(scr->valid&mVALID) || alert_confirm("Confirm Delete","Delete this screen?"))
3102 {
3103 Map.DoClearScreenCommand(screen);
3104 }
3105
3106 mark_save_dirty();
3107 return D_O_K;
3108 }
3109
3110 int32_t onDeleteMap()
3111 {
3112 if (alert_confirm("Confirm Delete","Clear this entire map?"))
3113 {
3114 Map.clearmap(false);
3115 refresh(rALL);
3116 mark_save_dirty();
3117 }
3118
3119 return D_O_K;
3120 }
3121
3122 int32_t onToggleDarkness()
3123 {
3124 Map.CurrScr()->flags^=4;
3125 refresh(rMAP+rMENU);
3126 mark_save_dirty();
3127 return D_O_K;
3128 }
3129
3130 int32_t onIncMap()
3131 {
3132 int32_t m=Map.getCurrMap();
3133 Map.setCurrMap(m+1>=map_count?0:m+1);
3134 Map.setlayertarget(); //Needed to refresh the screen info. -Z ( 26th March, 2019 )
3135
3136 refresh(rALL);
3137 return D_O_K;
3138 }
3139
3140 int32_t onDecMap()
3141 {
3142 int32_t m = Map.getCurrMap();
3143 Map.setCurrMap((m-1<0)?map_count-1:zc_min(m-1,map_count-1));
3144 // Map.setCurrScr(Map.getCurrScr()); //Needed to refresh the screen info. -Z ( 26th March, 2019 )
3145 Map.setlayertarget(); //Needed to refresh the screen info. -Z ( 26th March, 2019 )
3146
3147 Map.refresh_color();
3148
3149 refresh(rALL);
3150 return D_O_K;
3151 }
3152
3153
3154 int32_t onDefault_Pals()
3155 {
3156 if (alert_confirm("Confirm Reset","Reset all palette data?"))
3157 {
3158 mark_save_dirty();
3159
3160 if(!init_colordata(true, &header, &QMisc))
3161 {
3162 displayinfo("Error","Palette reset failed.");
3163 }
3164
3165 refresh_pal();
3166 }
3167
3168 return D_O_K;
3169 }
3170
3171 int32_t onDefault_Combos()
3172 {
3173 if (alert_confirm("Confirm Reset","Reset combo data?"))
3174 {
3175 mark_save_dirty();
3176
3177 if(!init_combos(true, &header))
3178 {
3179 displayinfo("Error","Combo reset failed.");
3180 }
3181
3182 refresh(rALL);
3183 }
3184
3185 return D_O_K;
3186 }
3187
3188 int32_t onDefault_Items()
3189 {
3190 if (alert_confirm("Confirm Reset","Reset all items?"))
3191 {
3192 mark_save_dirty();
3193 reset_items(true, &header);
3194 }
3195
3196 return D_O_K;
3197 }
3198
3199 int32_t onDefault_Weapons()
3200 {
3201 if (alert_confirm("Confirm Reset","Reset weapon/misc. sprite data?"))
3202 {
3203 mark_save_dirty();
3204 reset_wpns(true, &header);
3205 }
3206
3207 return D_O_K;
3208 }
3209
3210 int32_t onDefault_Guys()
3211 {
3212 if (alert_confirm("Confirm Reset","Reset all enemy/NPC data?"))
3213 {
3214 mark_save_dirty();
3215 reset_guys();
3216 }
3217
3218 return D_O_K;
3219 }
3220
3221
3222 int32_t onDefault_Tiles()
3223 {
3224 if (alert_confirm("Confirm Reset","Reset all tiles?"))
3225 {
3226 mark_save_dirty();
3227
3228 if(!init_tiles(true, &header))
3229 {
3230 displayinfo("Error","Tile reset failed.");
3231 }
3232
3233 refresh(rALL);
3234 }
3235
3236 return D_O_K;
3237 }
3238
3239 void change_sfx(SAMPLE *sfx1, SAMPLE *sfx2);
3240
3241 int32_t onDefault_SFX()
3242 {
3243 if (alert_confirm("Confirm Reset", "Reset all sound effects?"))
3244 {
3245 mark_save_dirty();
3246 SAMPLE *temp_sample;
3247
3248 for(int32_t i=1; i<WAV_COUNT; i++)
3249 {
3250 temp_sample = (SAMPLE *)sfxdata[zc_min(i,Z35)].dat;
3251 change_sfx(&customsfxdata[i], temp_sample);
3252 sprintf(sfx_string[i],"s%03d",i);
3253
3254 if(i<Z35)
3255 strcpy(sfx_string[i], old_sfx_string[i-1]);
3256 set_bit(customsfxflag, i<Z35?1:0, i-1);
3257 }
3258 }
3259
3260 return D_O_K;
3261 }
3262
3263
3264 int32_t onDefault_MapStyles()
3265 {
3266 if (alert_confirm("Confirm Reset", "Reset all map styles?"))
3267 {
3268 mark_save_dirty();
3269 reset_mapstyles(true, &QMisc);
3270 }
3271
3272 return D_O_K;
3273 }
3274
3275 int onScrollScreen(int dir, bool warp)
3276 {
3277 Map.scroll(dir,warp);
3278 return D_O_K;
3279 }
3280
3281 int32_t onComboColLeft()
3282 {
3283 if(draw_mode==dm_cpool||draw_mode==dm_auto)
3284 ;
3285 else if((First[current_combolist]>0)&&(draw_mode!=dm_alias))
3286 {
3287 First[current_combolist]-=1;
3288 clear_tooltip();
3289 refresh(rCOMBOS);
3290 }
3291 else if((combo_alistpos[current_comboalist]>0)&&(draw_mode==dm_alias))
3292 {
3293 combo_alistpos[current_comboalist]-=1;
3294 clear_tooltip();
3295 refresh(rCOMBOS);
3296 }
3297
3298 clear_keybuf();
3299 return D_O_K;
3300 }
3301
3302 int32_t onComboColRight()
3303 {
3304 auto& sqr = (draw_mode == dm_alias ? comboaliaslist[current_comboalist] : combolist[current_combolist]);
3305 if(draw_mode==dm_cpool||draw_mode==dm_auto)
3306 ;
3307 else if((First[current_combolist]<(MAXCOMBOS-(sqr.w*sqr.h)))&&(draw_mode!=dm_alias))
3308 {
3309 First[current_combolist]+=1;
3310 clear_tooltip();
3311 refresh(rCOMBOS);
3312 }
3313 else if((combo_alistpos[current_comboalist]<(MAXCOMBOALIASES-(sqr.w*sqr.h)))&&(draw_mode==dm_alias))
3314 {
3315 combo_alistpos[current_comboalist]+=1;
3316 clear_tooltip();
3317 refresh(rCOMBOS);
3318 }
3319
3320 clear_keybuf();
3321 return D_O_K;
3322 }
3323
3324 int32_t onComboColUp()
3325 {
3326 auto& sqr = (draw_mode == dm_alias ? comboaliaslist[current_comboalist] : combolist[current_combolist]);
3327 if(draw_mode==dm_cpool||draw_mode==dm_auto)
3328 ;
3329 else if((First[current_combolist]>0)&&(draw_mode!=dm_alias))
3330 {
3331 First[current_combolist]-=zc_min(First[current_combolist],sqr.w);
3332 clear_tooltip();
3333
3334 refresh(rCOMBOS);
3335 }
3336 else if((combo_alistpos[current_comboalist]>0)&&(draw_mode==dm_alias))
3337 {
3338 combo_alistpos[current_comboalist]-=zc_min(combo_alistpos[current_comboalist],sqr.w);
3339 clear_tooltip();
3340 refresh(rCOMBOS);
3341 }
3342
3343 clear_keybuf();
3344 return D_O_K;
3345 }
3346
3347 int32_t onComboColDown()
3348 {
3349 auto& sqr = (draw_mode == dm_alias ? comboaliaslist[current_comboalist] : combolist[current_combolist]);
3350
3351 if(draw_mode==dm_cpool||draw_mode==dm_auto)
3352 ;
3353 else if((First[current_combolist]<(MAXCOMBOS-(sqr.w*sqr.h)))&&(draw_mode!=dm_alias))
3354 {
3355 First[current_combolist]+=zc_min((MAXCOMBOS-sqr.w)-First[current_combolist],sqr.w);
3356 clear_tooltip();
3357 refresh(rCOMBOS);
3358 }
3359 else if((combo_alistpos[current_comboalist]<(MAXCOMBOALIASES-(comboaliaslist[0].w*comboaliaslist[0].h)))&&(draw_mode==dm_alias))
3360 {
3361 combo_alistpos[current_comboalist]+=zc_min((MAXCOMBOALIASES-sqr.w)-combo_alistpos[current_comboalist],sqr.w);
3362 clear_tooltip();
3363 refresh(rCOMBOS);
3364 }
3365
3366 clear_keybuf();
3367 return D_O_K;
3368 }
3369
3370 void scrollup(int j)
3371 {
3372 switch(draw_mode)
3373 {
3374 case dm_alias:
3375 {
3376 auto& sqr = comboaliaslist[j];
3377 if(combo_alistpos[j]>0)
3378 {
3379 if(CHECK_CTRL_CMD)
3380 {
3381 combo_alistpos[j]=0;
3382 clear_tooltip();
3383 }
3384 else
3385 {
3386 combo_alistpos[j]-=zc_min(combo_alistpos[j],(sqr.w*sqr.h));
3387 clear_tooltip();
3388 }
3389
3390 refresh(rCOMBOS);
3391 }
3392 break;
3393 }
3394 case dm_cpool:
3395 {
3396 auto& sqr = comboaliaslist[j];
3397 if(combo_pool_listpos[j]>0)
3398 {
3399 if(CHECK_CTRL_CMD)
3400 {
3401 combo_pool_listpos[j]=0;
3402 clear_tooltip();
3403 }
3404 else
3405 {
3406 combo_pool_listpos[j]-=zc_min(combo_pool_listpos[j],(sqr.w*sqr.h));
3407 clear_tooltip();
3408 }
3409
3410 refresh(rCOMBOS);
3411 }
3412 break;
3413 }
3414 case dm_auto:
3415 {
3416 auto& sqr = comboaliaslist[j];
3417 if (combo_auto_listpos[j] > 0)
3418 {
3419 if (CHECK_CTRL_CMD)
3420 {
3421 combo_auto_listpos[j] = 0;
3422 clear_tooltip();
3423 }
3424 else
3425 {
3426 combo_auto_listpos[j] -= zc_min(combo_auto_listpos[j], (sqr.w * sqr.h));
3427 clear_tooltip();
3428 }
3429
3430 refresh(rCOMBOS);
3431 }
3432 break;
3433 }
3434 default:
3435 {
3436 auto& sqr = combolist[j];
3437 if(First[j]>0)
3438 {
3439 if(CHECK_CTRL_CMD)
3440 {
3441 First[j]-=zc_min(First[j],256);
3442 clear_tooltip();
3443 }
3444 else
3445 {
3446 First[j]-=zc_min(First[j],(sqr.w*sqr.h));
3447 clear_tooltip();
3448 }
3449
3450 refresh(rCOMBOS);
3451 }
3452 break;
3453 }
3454 }
3455 }
3456 void scrolldown(int j)
3457 {
3458 switch(draw_mode)
3459 {
3460 case dm_alias:
3461 {
3462 auto& sqr = comboaliaslist[j];
3463 if(combo_alistpos[j]<(MAXCOMBOALIASES-(sqr.w*sqr.h)))
3464 {
3465 if(CHECK_CTRL_CMD)
3466 {
3467 combo_alistpos[j]=MAXCOMBOALIASES-(sqr.w*sqr.h);
3468 clear_tooltip();
3469 }
3470 else
3471 {
3472 combo_alistpos[j]=zc_min((MAXCOMBOALIASES-(sqr.w*sqr.h)),combo_alistpos[j]+(sqr.w*sqr.h));
3473 clear_tooltip();
3474 }
3475
3476 refresh(rCOMBOS);
3477 }
3478 break;
3479 }
3480 case dm_cpool:
3481 {
3482 auto& sqr = comboaliaslist[j];
3483 if(combo_pool_listpos[j]<(MAXCOMBOALIASES-(sqr.w*sqr.h)))
3484 {
3485 if(CHECK_CTRL_CMD)
3486 {
3487 combo_pool_listpos[j]=MAXCOMBOALIASES-(sqr.w*sqr.h);
3488 clear_tooltip();
3489 }
3490 else
3491 {
3492 combo_pool_listpos[j]=zc_min((MAXCOMBOALIASES-(sqr.w*sqr.h)),combo_pool_listpos[j]+(sqr.w*sqr.h));
3493 clear_tooltip();
3494 }
3495
3496 refresh(rCOMBOS);
3497 }
3498 break;
3499 }
3500 case dm_auto:
3501 {
3502 auto& sqr = comboaliaslist[j];
3503 if (combo_auto_listpos[j] < (MAXCOMBOALIASES - (sqr.w * sqr.h)))
3504 {
3505 if (CHECK_CTRL_CMD)
3506 {
3507 combo_auto_listpos[j] = MAXCOMBOALIASES - (sqr.w * sqr.h);
3508 clear_tooltip();
3509 }
3510 else
3511 {
3512 combo_auto_listpos[j] = zc_min((MAXCOMBOALIASES - (sqr.w * sqr.h)), combo_pool_listpos[j] + (sqr.w * sqr.h));
3513 clear_tooltip();
3514 }
3515
3516 refresh(rCOMBOS);
3517 }
3518 break;
3519 }
3520 default:
3521 {
3522 auto& sqr = combolist[j];
3523 if(First[j]<(MAXCOMBOS-(sqr.w*sqr.h)))
3524 {
3525 if(CHECK_CTRL_CMD)
3526 {
3527 First[j]=zc_min((MAXCOMBOS-sqr.w*sqr.h),First[j]+256);
3528 clear_tooltip();
3529 }
3530 else
3531 {
3532 First[j]=zc_min((MAXCOMBOS-(sqr.w*sqr.h)),First[j]+(sqr.w*sqr.h));
3533 clear_tooltip();
3534 }
3535
3536 refresh(rCOMBOS);
3537 }
3538 break;
3539 }
3540 }
3541 }
3542
3543 int32_t onPgUp()
3544 {
3545 switch(draw_mode)
3546 {
3547 case dm_alias:
3548 scrollup(current_comboalist);
3549 break;
3550 case dm_cpool:
3551 scrollup(current_cpoollist);
3552 break;
3553 case dm_auto:
3554 scrollup(current_cautolist);
3555 break;
3556 default:
3557 scrollup(current_combolist);
3558 break;
3559 }
3560 return D_O_K;
3561 }
3562
3563 int32_t onPgDn()
3564 {
3565 switch(draw_mode)
3566 {
3567 case dm_alias:
3568 scrolldown(current_comboalist);
3569 break;
3570 case dm_cpool:
3571 scrolldown(current_cpoollist);
3572 break;
3573 case dm_auto:
3574 scrolldown(current_cautolist);
3575 break;
3576 default:
3577 scrolldown(current_combolist);
3578 break;
3579 }
3580 return D_O_K;
3581 }
3582
3583 int32_t onIncreaseCSet()
3584 {
3585 if(draw_mode!=dm_alias)
3586 {
3587 CSet=wrap(CSet+1,0,13);
3588 refresh(rCOMBOS+rMENU+rCOMBO);
3589 }
3590 else
3591 {
3592 alias_cset_mod=wrap(alias_cset_mod+1,0,13);
3593 }
3594 return D_O_K;
3595 }
3596
3597 int32_t onDecreaseCSet()
3598 {
3599 if(draw_mode!=dm_alias)
3600 {
3601 CSet=wrap(CSet-1,0,13);
3602 refresh(rCOMBOS+rMENU+rCOMBO);
3603 }
3604 else
3605 {
3606 alias_cset_mod=wrap(alias_cset_mod-1,0,13);
3607 }
3608 return D_O_K;
3609 }
3610
3611 int32_t onGotoPage()
3612 {
3613 if (draw_mode==dm_alias)
3614 {
3615 static const int PER_PAGE = 260;
3616 if(optional<int> v = call_get_num("Scroll to Alias Page", 0, MAXCOMBOALIASES/PER_PAGE-1, 0))
3617 combo_alistpos[current_comboalist] = *v*PER_PAGE;
3618 }
3619 else if (draw_mode==dm_cpool)
3620 {
3621 static const int PER_PAGE = 260;
3622 if(optional<int> v = call_get_num("Scroll to Combo Pool Page", 0, MAXCOMBOPOOLS/PER_PAGE-1, 0))
3623 combo_pool_listpos[current_cpoollist] = *v*PER_PAGE;
3624 }
3625 else if (draw_mode == dm_auto)
3626 {
3627 static const int PER_PAGE = 260;
3628 if(optional<int> v = call_get_num("Scroll to Auto Combo Page", 0, MAXAUTOCOMBOS/PER_PAGE-1, 0))
3629 combo_auto_listpos[current_cautolist] = *v*PER_PAGE;
3630 }
3631 else
3632 {
3633 static const int PER_PAGE = 256;
3634 if(optional<int> v = call_get_num("Scroll to Combo Page", 0, MAXCOMBOS/PER_PAGE-1, 0))
3635 First[current_combolist] = *v*PER_PAGE;
3636 }
3637
3638 return D_O_K;
3639 }
3640
3641 static char track_number_str_buf[MIDI_TRACK_BUFFER_SIZE] = {0};
3642 const char *tracknumlist(int32_t index, int32_t *list_size)
3643 {
3644 //memset(track_number_str_buf,0,50);
3645 if(index>=0)
3646 {
3647 bound(index,0,255);
3648 std::string name = zcmusic_get_track_name(zcmusic, index);
3649 sprintf(track_number_str_buf,"%02d %s",index+1, name.c_str());
3650 return track_number_str_buf;
3651 }
3652
3653 *list_size=zcmusic_get_tracks(zcmusic);
3654 return NULL;
3655 }
3656
3657 12 static ListData tracknum_list(tracknumlist, &font);
3658
3659 static DIALOG change_track_dlg[] =
3660 {
3661 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
3662 12 { jwin_win_proc, 60-12, 40, 200-16, 72, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Select Track", NULL, NULL },
3663 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
3664 12 { jwin_droplist_proc, 72-12, 60+4, 161, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &tracknum_list, NULL, NULL },
3665 12 { jwin_button_proc, 70, 87, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
3666 12 { jwin_button_proc, 150, 87, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
3667 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
3668 };
3669 // return list_dlg[2].d1;
3670
3671 int32_t changeTrack()
3672 {
3673 restore_mouse();
3674 change_track_dlg[0].dp2=get_zc_font(font_lfont);
3675 change_track_dlg[2].d1=gme_track;
3676
3677 large_dialog(change_track_dlg);
3678
3679 if(do_zqdialog(change_track_dlg,2)==3)
3680 {
3681 gme_track=change_track_dlg[2].d1;
3682 zcmusic_change_track(zcmusic, gme_track);
3683 }
3684
3685 return D_O_K;
3686 }
3687
3688 void set_media_tunes()
3689 {
3690 media_menu.select_uid(MENUID_MEDIA_TUNES, true);
3691 media_menu.select_uid(MENUID_MEDIA_PLAYMUSIC, false);
3692 disable_hotkey(ZQKEY_AMBIENT_MUSIC, false);
3693 disable_hotkey(ZQKEY_PLAY_MUSIC, false);
3694
3695 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, true);
3696 disable_hotkey(ZQKEY_CHANGE_TRACK, true);
3697 }
3698
3699 int32_t playMusic()
3700 {
3701 char *ext;
3702 bool ismidi=false;
3703 char allmusic_types[256];
3704 sprintf(allmusic_types, "%s;mid", zcmusic_types);
3705
3706 if(prompt_for_existing_file_compat("Load Music",(char*)allmusic_types,NULL,midipath,false))
3707 {
3708 strcpy(midipath,temppath);
3709
3710 ext=get_extension(midipath);
3711
3712 if(
3713 (stricmp(ext,"ogg")==0)||
3714 (stricmp(ext,"mp3")==0)||
3715 (stricmp(ext,"it")==0)||
3716 (stricmp(ext,"xm")==0)||
3717 (stricmp(ext,"s3m")==0)||
3718 (stricmp(ext,"mod")==0)||
3719 (stricmp(ext,"spc")==0)||
3720 (stricmp(ext,"gym")==0)||
3721 (stricmp(ext,"nsf")==0)||
3722 (stricmp(ext,"gbs")==0)||
3723 (stricmp(ext,"vgm")==0)
3724 )
3725 {
3726 ismidi=false;
3727 }
3728 else if((stricmp(ext,"mid")==0))
3729 {
3730 ismidi=true;
3731 }
3732 else
3733 {
3734 return D_O_K;
3735 }
3736
3737 zc_stop_midi();
3738
3739 if(zcmusic != NULL)
3740 {
3741 zcmusic_stop(zcmusic);
3742 zcmusic_unload_file(zcmusic);
3743 zcmusic = NULL;
3744 zcmixer->newtrack = NULL;
3745 }
3746
3747 if(ismidi)
3748 {
3749 packfile_password("");
3750 if((song=load_midi(midipath))!=NULL)
3751 {
3752 if(zc_play_midi(song,true)==0)
3753 {
3754 media_menu.select_uid(MENUID_MEDIA_TUNES, false);
3755 media_menu.select_uid(MENUID_MEDIA_PLAYMUSIC, true);
3756 disable_hotkey(ZQKEY_AMBIENT_MUSIC, false);
3757 disable_hotkey(ZQKEY_PLAY_MUSIC, false);
3758
3759 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, true);
3760 disable_hotkey(ZQKEY_CHANGE_TRACK, true);
3761 }
3762 }
3763 }
3764 else
3765 {
3766 gme_track=0;
3767 zcmusic = (ZCMUSIC*)zcmusic_load_file(midipath);
3768
3769 if(zcmusic!=NULL)
3770 {
3771 media_menu.select_uid(MENUID_MEDIA_TUNES, false);
3772 media_menu.select_uid(MENUID_MEDIA_PLAYMUSIC, true);
3773 disable_hotkey(ZQKEY_AMBIENT_MUSIC, false);
3774 disable_hotkey(ZQKEY_PLAY_MUSIC, false);
3775
3776 bool distrack = zcmusic_get_tracks(zcmusic)<2;
3777 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, distrack);
3778 disable_hotkey(ZQKEY_CHANGE_TRACK, distrack);
3779
3780 zcmusic_play(zcmusic, midi_volume);
3781 }
3782 }
3783 }
3784
3785 return D_O_K;
3786 }
3787
3788 int32_t playZCForever()
3789 {
3790 stopMusic();
3791
3792 zcmusic = zcmusic_load_file("assets/zc/ZC_Forever_HD.mp3");
3793 if (zcmusic)
3794 {
3795 zcmusic_play(zcmusic, midi_volume);
3796 set_media_tunes();
3797 }
3798 return D_O_K;
3799 }
3800
3801 // It took awhile to get these values right, so no meddlin'!
3802 int32_t playTune1()
3803 {
3804 return playTune(0);
3805 }
3806 int32_t playTune2()
3807 {
3808 return playTune(81);
3809 }
3810 int32_t playTune3()
3811 {
3812 return playTune(233);
3813 }
3814 int32_t playTune4()
3815 {
3816 return playTune(553);
3817 }
3818 int32_t playTune5()
3819 {
3820 return playTune(814);
3821 }
3822 int32_t playTune6()
3823 {
3824 return playTune(985);
3825 }
3826 int32_t playTune7()
3827 {
3828 return playTune(1153);
3829 }
3830 int32_t playTune8()
3831 {
3832 return playTune(1333);
3833 }
3834 int32_t playTune9()
3835 {
3836 return playTune(1556);
3837 }
3838 int32_t playTune10()
3839 {
3840 return playTune(1801);
3841 }
3842 int32_t playTune11()
3843 {
3844 return playTune(2069);
3845 }
3846 int32_t playTune12()
3847 {
3848 return playTune(2189);
3849 }
3850 int32_t playTune13()
3851 {
3852 return playTune(2569);
3853 }
3854 int32_t playTune14()
3855 {
3856 return playTune(2753);
3857 }
3858 int32_t playTune15()
3859 {
3860 return playTune(2856);
3861 }
3862 int32_t playTune16()
3863 {
3864 return playTune(3042);
3865 }
3866 int32_t playTune17()
3867 {
3868 return playTune(3125);
3869 }
3870 int32_t playTune18()
3871 {
3872 return playTune(3217);
3873 }
3874 int32_t playTune19()
3875 {
3876 return playTune(3296);
3877 }
3878
3879 int32_t playTune(int32_t pos)
3880 {
3881 zc_stop_midi();
3882
3883 if(zcmusic != NULL)
3884 {
3885 zcmusic_stop(zcmusic);
3886 zcmusic_unload_file(zcmusic);
3887 zcmusic = NULL;
3888 zcmixer->newtrack = NULL;
3889 }
3890
3891 if(zc_play_midi(asset_tunes_midi,true)==0)
3892 {
3893 zc_midi_seek(pos);
3894 set_media_tunes();
3895 }
3896
3897 return D_O_K;
3898 }
3899
3900 int32_t stopMusic()
3901 {
3902 zc_stop_midi();
3903
3904 if(zcmusic != NULL)
3905 {
3906 zcmusic_stop(zcmusic);
3907 zcmusic_unload_file(zcmusic);
3908 zcmusic = NULL;
3909 zcmixer->newtrack = NULL;
3910 }
3911
3912 media_menu.select_uid(MENUID_MEDIA_TUNES, false);
3913 media_menu.select_uid(MENUID_MEDIA_PLAYMUSIC, false);
3914 disable_hotkey(ZQKEY_AMBIENT_MUSIC, false);
3915 disable_hotkey(ZQKEY_PLAY_MUSIC, false);
3916
3917 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, true);
3918 disable_hotkey(ZQKEY_CHANGE_TRACK, true);
3919 return D_O_K;
3920 }
3921
3922 static int32_t gamemisc1_list[] =
3923 {
3924 5,6,7,8,
3925 9,10,11,12,
3926
3927 37,38,39,40,
3928 41,42,43,44,
3929
3930 71,72,73,74,
3931 75,76,77,78,
3932
3933 -1
3934 };
3935
3936 static int32_t gamemisc2_list[] =
3937 {
3938 13,14,15,16,
3939 17,18,19,20,
3940
3941 45,46,47,48,
3942 49,50,51,52,
3943
3944 79,80,81,82,
3945 83,84,85,86,
3946
3947 -1
3948 };
3949
3950 static int32_t gamemisc3_list[] =
3951 {
3952 21,22,23,24,
3953 25,26,27,28,
3954
3955 53,54,55,56,
3956 57,58,59,60,
3957
3958 87,88,89,90,
3959 91,92,93,94,
3960
3961 -1
3962 };
3963
3964 static int32_t gamemisc4_list[] =
3965 {
3966 29,30,31,32,
3967 33,34,35,36,
3968
3969 61,62,63,64,
3970 65,66,67,68,
3971
3972 95,96,97,98,
3973 99,100,101,102,
3974
3975 -1
3976 };
3977
3978 static TABPANEL gamemisc_tabs[] =
3979 {
3980 // (text)
3981 { (char *)" Misc[0-7] ", D_SELECTED, gamemisc1_list, 0, NULL },
3982 { (char *)" Misc[8-15] ", 0, gamemisc2_list, 0, NULL },
3983 { (char *)" Misc[16-23] ", 0, gamemisc3_list, 0, NULL },
3984 { (char *)" Misc[24-31] ", 0, gamemisc4_list, 0, NULL },
3985 { NULL, 0, NULL, 0, NULL }
3986 };
3987
3988 //to do: Make string boxes larger, and split into two tabs.
3989 static DIALOG gamemiscarray_dlg[] =
3990 {
3991 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
3992
3993 { jwin_win_proc, 0, 10, 310, 224, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Game->Misc[]", NULL, NULL },
3994 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
3995 { jwin_tab_proc, 3, 26, 304, 174, vc(14), vc(1), 0, 0, 1, 0, (void *) gamemisc_tabs, NULL, (void *)gamemiscarray_dlg },
3996 { d_dummy_proc, 240, 144, 40, 8, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
3997 { d_dummy_proc, 240, 144, 40, 8, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
3998
3999 //5
4000 { jwin_edit_proc, 8, 42, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4001 { jwin_edit_proc, 8, 42+20, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4002 { jwin_edit_proc, 8, 42+40, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4003 //8
4004 { jwin_edit_proc, 8, 42+60, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4005 { jwin_edit_proc, 8, 42+80, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4006 { jwin_edit_proc, 8, 42+100, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4007 { jwin_edit_proc, 8, 42+120, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4008 { jwin_edit_proc, 8, 42+140, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4009 //13
4010 { jwin_edit_proc, 8, 42, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4011 { jwin_edit_proc, 8, 42+20, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4012 { jwin_edit_proc, 8, 42+40, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4013 { jwin_edit_proc, 8, 42+60, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4014 { jwin_edit_proc, 8, 42+80, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4015 //18
4016 { jwin_edit_proc, 8, 42+100, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4017 { jwin_edit_proc, 8, 42+120, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4018 { jwin_edit_proc, 8, 42+140, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4019 { jwin_edit_proc, 8, 42, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4020 { jwin_edit_proc, 8, 42+20, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4021 //23
4022 { jwin_edit_proc, 8, 42+40, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4023 { jwin_edit_proc, 8, 42+60, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4024 { jwin_edit_proc, 8, 42+80, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4025 { jwin_edit_proc, 8, 42+100, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4026 { jwin_edit_proc, 8, 42+120, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4027 //28
4028 { jwin_edit_proc, 8, 42+140, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4029 { jwin_edit_proc, 8, 42, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4030 { jwin_edit_proc, 8, 42+20, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4031 { jwin_edit_proc, 8, 42+40, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4032 { jwin_edit_proc, 8, 42+60, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4033 //33
4034 { jwin_edit_proc, 8, 42+80, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4035 { jwin_edit_proc, 8, 42+100, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4036 { jwin_edit_proc, 8, 42+120, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4037 { jwin_edit_proc, 8, 42+140, 100-12, 16, vc(12), vc(1), 0, 0, 64, 0, NULL, NULL, NULL },
4038 //37
4039 { jwin_numedit_swap_zsint_proc, 96, 42, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4040 { jwin_numedit_swap_zsint_proc, 96, 42+20, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4041 //39
4042 { jwin_numedit_swap_zsint_proc, 96, 42+40, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4043 { jwin_numedit_swap_zsint_proc, 96, 42+60, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4044 { jwin_numedit_swap_zsint_proc, 96, 42+80, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4045 { jwin_numedit_swap_zsint_proc, 96, 42+100, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4046 { jwin_numedit_swap_zsint_proc, 96, 42+120, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4047 //44
4048 { jwin_numedit_swap_zsint_proc, 96, 42+140, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4049 { jwin_numedit_swap_zsint_proc, 96, 42, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4050 { jwin_numedit_swap_zsint_proc, 96, 42+20, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4051
4052 { jwin_numedit_swap_zsint_proc, 96, 42+40, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4053 { jwin_numedit_swap_zsint_proc, 96, 42+60, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4054 //49
4055 { jwin_numedit_swap_zsint_proc, 96, 42+80, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4056 { jwin_numedit_swap_zsint_proc, 96, 42+100, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4057 { jwin_numedit_swap_zsint_proc, 96, 42+120, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4058 { jwin_numedit_swap_zsint_proc, 96, 42+140, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4059 { jwin_numedit_swap_zsint_proc, 96, 42, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4060 //54
4061 { jwin_numedit_swap_zsint_proc, 96, 42+20, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4062 { jwin_numedit_swap_zsint_proc, 96, 42+40, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4063 { jwin_numedit_swap_zsint_proc, 96, 42+60, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4064 { jwin_numedit_swap_zsint_proc, 96, 42+80, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4065 { jwin_numedit_swap_zsint_proc, 96, 42+100, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4066 //59
4067 { jwin_numedit_swap_zsint_proc, 96, 42+120, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4068 { jwin_numedit_swap_zsint_proc, 96, 42+140, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4069 { jwin_numedit_swap_zsint_proc, 96, 42, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4070 { jwin_numedit_swap_zsint_proc, 96, 42+20, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4071 { jwin_numedit_swap_zsint_proc, 96, 42+40, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4072 //64
4073 { jwin_numedit_swap_zsint_proc, 96, 42+60, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4074 { jwin_numedit_swap_zsint_proc, 96, 42+80, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4075 { jwin_numedit_swap_zsint_proc, 96, 42+100, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4076 { jwin_numedit_swap_zsint_proc, 96, 42+120, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4077 { jwin_numedit_swap_zsint_proc, 96, 42+140, 60, 16, vc(12), vc(1), 0, 0, 12, 0, NULL, NULL, NULL },
4078 //69
4079 { jwin_button_proc, 70, 204, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
4080 { jwin_button_proc, 170, 204, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
4081
4082 //71
4083 { jwin_swapbtn_proc, 156, 42, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4084 { jwin_swapbtn_proc, 156, 62, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4085 { jwin_swapbtn_proc, 156, 82, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4086 { jwin_swapbtn_proc, 156, 102, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4087 { jwin_swapbtn_proc, 156, 122, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4088 { jwin_swapbtn_proc, 156, 142, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4089 { jwin_swapbtn_proc, 156, 162, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4090 { jwin_swapbtn_proc, 156, 182, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4091 //79
4092 { jwin_swapbtn_proc, 156, 42, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4093 { jwin_swapbtn_proc, 156, 62, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4094 { jwin_swapbtn_proc, 156, 82, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4095 { jwin_swapbtn_proc, 156, 102, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4096 { jwin_swapbtn_proc, 156, 122, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4097 { jwin_swapbtn_proc, 156, 142, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4098 { jwin_swapbtn_proc, 156, 162, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4099 { jwin_swapbtn_proc, 156, 182, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4100 //87
4101 { jwin_swapbtn_proc, 156, 42, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4102 { jwin_swapbtn_proc, 156, 62, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4103 { jwin_swapbtn_proc, 156, 82, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4104 { jwin_swapbtn_proc, 156, 102, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4105 { jwin_swapbtn_proc, 156, 122, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4106 { jwin_swapbtn_proc, 156, 142, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4107 { jwin_swapbtn_proc, 156, 162, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4108 { jwin_swapbtn_proc, 156, 182, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4109 //95
4110 { jwin_swapbtn_proc, 156, 42, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4111 { jwin_swapbtn_proc, 156, 62, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4112 { jwin_swapbtn_proc, 156, 82, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4113 { jwin_swapbtn_proc, 156, 102, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4114 { jwin_swapbtn_proc, 156, 122, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4115 { jwin_swapbtn_proc, 156, 142, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4116 { jwin_swapbtn_proc, 156, 162, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4117 { jwin_swapbtn_proc, 156, 182, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4118
4119 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
4120 };
4121
4122 // +----------+
4123 // | |
4124 // | View Pic |
4125 // | |
4126 // | |
4127 // | |
4128 // +----------+
4129
4130 BITMAP *pic=NULL;
4131 BITMAP *bmap=NULL;
4132 PALETTE picpal;
4133 PALETTE mappal;
4134 int32_t picx=0,picy=0,mapx=0,mapy=0,pblack,pwhite;
4135
4136 double picscale=1.0,mapscale=1.0;
4137 bool vp_showpal=true, vp_showsize=true, vp_center=true;
4138
4139 //INLINE int32_t pal_sum(RGB p) { return p.r + p.g + p.b; }
4140
4141 void get_bw(RGB *pal,int32_t &black,int32_t &white)
4142 {
4143 black=white=1;
4144
4145 for(int32_t i=1; i<256; i++)
4146 {
4147 if(pal_sum(pal[i])<pal_sum(pal[black]))
4148 black=i;
4149
4150 if(pal_sum(pal[i])>pal_sum(pal[white]))
4151 white=i;
4152 }
4153 }
4154
4155 void draw_bw_mouse(int32_t white, int32_t old_mouse, int32_t new_mouse)
4156 {
4157 blit(mouse_bmp[old_mouse][0],mouse_bmp[new_mouse][0],0,0,0,0,16,16);
4158
4159 for(int32_t y=0; y<16; y++)
4160 {
4161 for(int32_t x=0; x<16; x++)
4162 {
4163 if(getpixel(mouse_bmp[new_mouse][0],x,y)!=0)
4164 {
4165 putpixel(mouse_bmp[new_mouse][0],x,y,white);
4166 }
4167 }
4168 }
4169 }
4170
4171 int32_t load_the_pic(BITMAP **dst, PALETTE dstpal)
4172 {
4173 PALETTE temppal;
4174
4175 for(int32_t i=0; i<256; i++)
4176 {
4177 temppal[i]=dstpal[i];
4178 dstpal[i]=RAMpal[i];
4179 }
4180
4181 // set up the new palette
4182 for(int32_t i=0; i<64; i++)
4183 {
4184 dstpal[i].r = i;
4185 dstpal[i].g = i;
4186 dstpal[i].b = i;
4187 }
4188
4189 zc_set_palette(dstpal);
4190
4191 BITMAP *graypic = create_bitmap_ex(8,screen->w,screen->h);
4192 int32_t _w = screen->w-1;
4193 int32_t _h = screen->h-1;
4194
4195 // gray scale the current frame
4196 for(int32_t y=0; y<_h; y++)
4197 {
4198 for(int32_t x=0; x<_w; x++)
4199 {
4200 int32_t c = screen->line[y][x];
4201 int32_t gray = zc_min((temppal[c].r*42 + temppal[c].g*75 + temppal[c].b*14) >> 7, 63);
4202 graypic->line[y][x] = gray;
4203 }
4204 }
4205
4206 blit(graypic,screen,0,0,0,0,screen->w,screen->h);
4207 destroy_bitmap(graypic);
4208 #ifdef __GNUC__
4209 #pragma GCC diagnostic ignored "-Wformat-overflow"
4210 #endif
4211 char extbuf[2][80];
4212 memset(extbuf[0],0,80);
4213 memset(extbuf[1],0,80);
4214 sprintf(extbuf[0], "View Image (%s", snapshotformat_str[0][1]);
4215 strcpy(extbuf[1], snapshotformat_str[0][1]);
4216
4217 for(int32_t i=1; i<ssfmtMAX; ++i)
4218 {
4219 sprintf(extbuf[0], "%s, %s", extbuf[0], snapshotformat_str[i][1]);
4220 sprintf(extbuf[1], "%s;%s", extbuf[1], snapshotformat_str[i][1]);
4221 }
4222
4223 sprintf(extbuf[0], "%s)", extbuf[0]);
4224 #ifdef __GNUC__
4225 #pragma GCC diagnostic pop
4226 #endif
4227
4228 int32_t gotit = prompt_for_existing_file_compat(extbuf[0],extbuf[1],NULL,imagepath,true);
4229
4230 if(!gotit)
4231 {
4232 zc_set_palette(temppal);
4233 get_palette(dstpal);
4234 return 1;
4235 }
4236
4237 strcpy(imagepath,temppath);
4238
4239 if(*dst)
4240 {
4241 destroy_bitmap(*dst);
4242 }
4243
4244 for(int32_t i=0; i<256; i++)
4245 {
4246 dstpal[i].r = 0;
4247 dstpal[i].g = 0;
4248 dstpal[i].b = 0;
4249 }
4250
4251 *dst = load_bitmap(imagepath,picpal);
4252
4253 if(!*dst)
4254 {
4255 displayinfo("Error",fmt::format("Error loading image: {}",imagepath));
4256 return 2;
4257 }
4258
4259 // get_bw(picpal,pblack,pwhite);
4260 // draw_bw_mouse(pwhite);
4261 // gui_bg_color = pblack;
4262 // gui_fg_color = pwhite;
4263
4264 if(vp_center)
4265 {
4266 picx=picy=0;
4267 }
4268 else
4269 {
4270 picx=(*dst)->w-zq_screen_w;
4271 picy=(*dst)->h-zq_screen_h;
4272 }
4273
4274 return 0;
4275 }
4276 int load_the_pic_new(BITMAP **dst, PALETTE dstpal)
4277 {
4278 #ifdef __GNUC__
4279 #pragma GCC diagnostic ignored "-Wformat-overflow"
4280 #endif
4281 char extbuf[2][80];
4282 memset(extbuf[0],0,80);
4283 memset(extbuf[1],0,80);
4284 sprintf(extbuf[0], "View Image (%s", snapshotformat_str[0][1]);
4285 strcpy(extbuf[1], snapshotformat_str[0][1]);
4286
4287 for(int32_t i=1; i<ssfmtMAX; ++i)
4288 {
4289 sprintf(extbuf[0], "%s, %s", extbuf[0], snapshotformat_str[i][1]);
4290 sprintf(extbuf[1], "%s;%s", extbuf[1], snapshotformat_str[i][1]);
4291 }
4292
4293 sprintf(extbuf[0], "%s)", extbuf[0]);
4294 #ifdef __GNUC__
4295 #pragma GCC diagnostic pop
4296 #endif
4297
4298 int32_t gotit = prompt_for_existing_file_compat(extbuf[0],extbuf[1],NULL,imagepath,true);
4299
4300 if(!gotit)
4301 return 1;
4302
4303 strcpy(imagepath,temppath);
4304
4305 if(*dst)
4306 destroy_bitmap(*dst);
4307
4308 for(int32_t i=0; i<256; i++)
4309 {
4310 dstpal[i].r = 0;
4311 dstpal[i].g = 0;
4312 dstpal[i].b = 0;
4313 }
4314
4315 *dst = load_bitmap(imagepath,dstpal);
4316
4317 if(!*dst)
4318 {
4319 displayinfo("Error",fmt::format("Error loading image: {}",imagepath));
4320 return 2;
4321 }
4322
4323 if(vp_center)
4324 {
4325 picx=picy=0;
4326 }
4327 else
4328 {
4329 picx=(*dst)->w-zq_screen_w;
4330 picy=(*dst)->h-zq_screen_h;
4331 }
4332
4333 return 0;
4334 }
4335
4336 int32_t saveMapAsImage(ALLEGRO_BITMAP* bitmap)
4337 {
4338 char buf[200];
4339 int32_t num=0;
4340
4341 do
4342 {
4343 snprintf(buf, 200, "%szquest_map%05d.%s", get_snap_str(), ++num, snapshotformat_str[SnapshotFormat][1]);
4344 buf[199]='\0';
4345 }
4346 while(num<99999 && exists(buf));
4347
4348 if (num >= 99999)
4349 InfoDialog("Error", "Failed to save map image! Max map images (99999) already exist!").show();
4350 else if (!al_save_bitmap(buf, bitmap))
4351 InfoDialog("Error", fmt::format("Failed to save map image\n'{}'.", buf)).show();
4352
4353 return D_O_K;
4354 }
4355
4356 int32_t onViewPic()
4357 {
4358 return launchPicViewer(&pic,picpal,picx,picy,picscale,false);
4359 }
4360
4361 int32_t launchPicViewer(BITMAP **pictoview, PALETTE pal, int32_t& px2, int32_t& py2, double& scale, bool isviewingmap, bool skipmenu)
4362 {
4363 restore_mouse();
4364 BITMAP *buf;
4365 bool done=false, redraw=true;
4366
4367 popup_zqdialog_start();
4368
4369 // Always call load_the_map() when viewing the map.
4370 if((!*pictoview || isviewingmap) && (isviewingmap ? load_the_map(skipmenu) : load_the_pic(pictoview,pal)))
4371 {
4372 zc_set_palette(RAMpal);
4373 mapview_close();
4374 popup_zqdialog_end();
4375 return D_O_K;
4376 }
4377
4378 MapViewRTI* rti_map_view = mapview_get_rti();
4379
4380 zq_freeze_all_rti();
4381 if (isviewingmap)
4382 rti_map_view->freeze = false;
4383 else
4384 get_screen_rti()->freeze = false;
4385
4386 get_bw(pal,pblack,pwhite);
4387
4388 int32_t oldfgcolor = gui_fg_color;
4389 int32_t oldbgcolor = gui_bg_color;
4390
4391 buf = create_bitmap_ex(8,zq_screen_w,zq_screen_h);
4392
4393 if(!buf)
4394 {
4395 displayinfo("Error","Error creating temp bitmap");
4396 mapview_close();
4397 popup_zqdialog_end();
4398 return D_O_K;
4399 }
4400
4401 static LegacyBitmapRTI viewer_overlay_rti("viewer_overlay");
4402 viewer_overlay_rti.set_size(buf->w, buf->h);
4403 viewer_overlay_rti.a4_bitmap = buf;
4404 viewer_overlay_rti.transparency_index = 15;
4405 viewer_overlay_rti.freeze = false;
4406 get_root_rti()->add_child(&viewer_overlay_rti);
4407
4408 zc_set_palette(pal);
4409
4410 if(isviewingmap)
4411 {
4412 set_center_root_rti(false);
4413
4414 int sw = rti_map_view->width / 16;
4415 int sh = rti_map_view->height / 8;
4416 int screen = Map.getCurrScr();
4417 if (screen >= 0x00 && screen <= 0x7F)
4418 {
4419 auto root_transform = get_root_rti()->get_transform();
4420 int dw = al_get_display_width(all_get_display()) / root_transform.xscale;
4421 int dh = al_get_display_height(all_get_display()) / root_transform.yscale;
4422 mapx = (-(screen % 16) * sw - sw/2 + dw/2);
4423 mapy = (-(screen / 16) * sh - sh/2 + dh/2);
4424 }
4425 }
4426
4427 const double MIN_SCALE = 0.1;
4428 const double MAX_SCALE = 5.0;
4429 auto mouse_x = gui_mouse_x();
4430 auto mouse_y = gui_mouse_y();
4431 int mouse_off_x = 0, mouse_off_y = 0;
4432 double old_scale = scale;
4433 bool mouse_down = false;
4434
4435 do
4436 {
4437 HANDLE_CLOSE_ZQDLG();
4438 if(exiting_program) break;
4439 int w, h;
4440 if (isviewingmap)
4441 {
4442 w = rti_map_view->width;
4443 h = rti_map_view->height;
4444 }
4445 else
4446 {
4447 w = (*pictoview)->w;
4448 h = (*pictoview)->h;
4449 }
4450
4451 if (isviewingmap)
4452 {
4453 auto root_transform = get_root_rti()->get_transform();
4454 int dw = al_get_display_width(all_get_display()) / root_transform.xscale;
4455 int dh = al_get_display_height(all_get_display()) / root_transform.yscale;
4456 mapx = std::max(mapx, (int)(-w*scale + dw));
4457 mapy = std::max(mapy, (int)(-h*scale + dh));
4458 mapx = std::min(mapx, 0);
4459 mapy = std::min(mapy, 0);
4460 rti_map_view->set_transform({mapx, mapy, (float)scale, (float)scale});
4461 }
4462
4463 if(redraw)
4464 {
4465 clear_to_color(buf,15);
4466
4467 if (!isviewingmap)
4468 stretch_blit(*pictoview, buf, 0, 0, w, h,
4469 int32_t(zq_screen_w + (px2 - w) * scale) / 2, int32_t(zq_screen_h + (py2 - h) * scale) / 2,
4470 int32_t(w * scale), int32_t(h * scale));
4471
4472 if(vp_showpal)
4473 for(int32_t i=0; i<256; i++)
4474 rectfill(buf,((i&15)<<2)+zq_screen_w-64,((i>>4)<<2)+zq_screen_h-64,((i&15)<<2)+zq_screen_w-64+3,((i>>4)<<2)+zq_screen_h-64+3,i);
4475
4476 if(vp_showsize)
4477 {
4478 textprintf_ex(buf,font,0,zq_screen_h-8,pwhite,pblack,"%dx%d %.2f%%",w,h,scale*100.0);
4479 }
4480
4481 if (!isviewingmap)
4482 blit(buf,screen,0,0,0,0,zq_screen_w,zq_screen_h);
4483 redraw=false;
4484 }
4485
4486 custom_vsync();
4487
4488 int32_t step = 16;
4489 double scale_step = 0.95;
4490 double scale_bigstep = 2.0;
4491
4492 if(scale < 1.0)
4493 step = int32_t(4.0/ scale);
4494
4495 bool shift = (key[KEY_LSHIFT] || key[KEY_RSHIFT]);
4496 bool ctrl = CHECK_CTRL_CMD;
4497 if (shift)
4498 step <<= 2;
4499 if (ctrl)
4500 step >>= 1;
4501 if (shift && ctrl)
4502 {
4503 scale_step = 0.90;
4504 scale_bigstep = 4.0;
4505 }
4506 else if (shift)
4507 {
4508 scale_step = 0.80;
4509 scale_bigstep = 3.0;
4510 }
4511 else if(ctrl)
4512 {
4513 scale_step = 0.975;
4514 scale_bigstep = 1.5;
4515 }
4516
4517 if(key[KEY_UP])
4518 {
4519 py2+=step;
4520 redraw=true;
4521 }
4522
4523 if(key[KEY_DOWN])
4524 {
4525 py2-=step;
4526 redraw=true;
4527 }
4528
4529 if(key[KEY_LEFT])
4530 {
4531 px2+=step;
4532 redraw=true;
4533 }
4534
4535 if(key[KEY_RIGHT])
4536 {
4537 px2-=step;
4538 redraw=true;
4539 }
4540
4541 if (bool mouse_down_now = (gui_mouse_b() & 1); mouse_down_now != mouse_down)
4542 {
4543 mouse_down = mouse_down_now;
4544 if (mouse_down)
4545 {
4546 mouse_x = gui_mouse_x();
4547 mouse_y = gui_mouse_y();
4548 mouse_off_x = px2;
4549 mouse_off_y = py2;
4550 }
4551 }
4552
4553 if (mouse_down)
4554 {
4555 if (abs(old_scale - scale) > 0.01)
4556 {
4557 mouse_x = gui_mouse_x();
4558 mouse_y = gui_mouse_y();
4559 mouse_off_x = px2;
4560 mouse_off_y = py2;
4561 old_scale = scale;
4562 }
4563 px2 = mouse_off_x + (gui_mouse_x() - mouse_x);
4564 py2 = mouse_off_y + (gui_mouse_y() - mouse_y);
4565 }
4566
4567 if (mouse_z)
4568 {
4569 double new_scale = scale;
4570 for (int q = 0; q < mouse_z; ++q)
4571 new_scale /= scale_step;
4572 for (int q = 0; q > mouse_z; --q)
4573 new_scale *= scale_step;
4574 position_mouse_z(0);
4575
4576 auto mx = (gui_mouse_x() - px2) / scale;
4577 auto my = (gui_mouse_y() - py2) / scale;
4578 scale = vbound(new_scale, MAX_SCALE, MIN_SCALE);
4579
4580 px2 = gui_mouse_x() - (mx * scale);
4581 py2 = gui_mouse_y() - (my * scale);
4582 }
4583
4584 if(keypressed() && !redraw)
4585 switch(readkey()>>8)
4586 {
4587 case KEY_PGUP:
4588 scale *= scale_step;
4589
4590 if(scale<MIN_SCALE) scale = MIN_SCALE;
4591
4592 redraw=true;
4593 break;
4594
4595 case KEY_PGDN:
4596 scale /= scale_step;
4597
4598 if(scale>MAX_SCALE) scale = MAX_SCALE;
4599
4600 redraw = true;
4601 break;
4602
4603 case KEY_HOME:
4604 scale /= scale_bigstep;
4605
4606 if(scale<MIN_SCALE) scale = MIN_SCALE;
4607
4608 redraw = true;
4609 break;
4610
4611 case KEY_END:
4612 scale *= scale_bigstep;
4613
4614 if(scale>MAX_SCALE) scale = MAX_SCALE;
4615
4616 redraw = true;
4617 break;
4618
4619 case KEY_TILDE:
4620 scale = 0.5;
4621 redraw = true;
4622 break;
4623
4624 case KEY_Z:
4625 px2 = w-zq_screen_w;
4626 py2 = h-zq_screen_h;
4627 vp_center = false;
4628 redraw = true;
4629 break;
4630
4631 case KEY_1:
4632 scale = 1.0;
4633 redraw = true;
4634 break;
4635
4636 case KEY_2:
4637 scale = 2.0;
4638 redraw = true;
4639 break;
4640
4641 case KEY_3:
4642 scale = 3.0;
4643 redraw = true;
4644 break;
4645
4646 case KEY_4:
4647 scale = 4.0;
4648 redraw = true;
4649 break;
4650
4651 case KEY_5:
4652 scale = 5.0;
4653 redraw = true;
4654 break;
4655
4656 case KEY_C:
4657 px2 = py2 = 0;
4658 redraw = vp_center = true;
4659 break;
4660
4661 case KEY_S:
4662 vp_showsize = !vp_showsize;
4663 redraw = true;
4664 break;
4665
4666 case KEY_D:
4667 vp_showpal = !vp_showpal;
4668 redraw = true;
4669 break;
4670
4671 case KEY_P:
4672 if(isviewingmap) break;
4673
4674 case KEY_ESC:
4675 done = true;
4676 break;
4677
4678 case KEY_SPACE:
4679 mapview_close();
4680 if(isviewingmap ? load_the_map(skipmenu) : load_the_pic(pictoview,pal)==2)
4681 {
4682 done = true;
4683 }
4684 else
4685 {
4686 redraw = true;
4687 gui_bg_color = pblack;
4688 gui_fg_color = pwhite;
4689 scale = 1.0;
4690 zc_set_palette(pal);
4691 }
4692
4693 get_bw(pal,pblack,pwhite);
4694 break;
4695 }
4696 }
4697 while(!done);
4698
4699 destroy_bitmap(buf);
4700 zc_set_palette(RAMpal);
4701 gui_fg_color = oldfgcolor;
4702 gui_bg_color = oldbgcolor;
4703
4704 position_mouse_z(0);
4705 viewer_overlay_rti.remove();
4706 set_center_root_rti(true);
4707 mapview_close();
4708 popup_zqdialog_end();
4709 return D_O_K;
4710 }
4711
4712 static DIALOG loadmap_dlg[] =
4713 {
4714 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3)
4715 { jwin_win_proc, 0, 0, 225, 143, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "View Map", NULL, NULL },
4716 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
4717 { jwin_text_proc, 32, 26, 96, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Resolution", NULL, NULL },
4718 // 3
4719 { jwin_radio_proc, 16, 36, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "1/4 - 1024x352", NULL, NULL },
4720 { jwin_radio_proc, 16, 46, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "1/2 - 2048x704", NULL, NULL },
4721 { jwin_radio_proc, 16, 56, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "Full - 4096x1408", NULL, NULL },
4722 { jwin_text_proc, 144, 26, 97, 9, vc(11), vc(1), 0, 0, 0, 0, (void *) "Options", NULL, NULL },
4723 // 7
4724 { jwin_check_proc, 144, 36, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Solidity", NULL, NULL },
4725 { jwin_check_proc, 144, 46, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Flags", NULL, NULL },
4726 { jwin_check_proc, 144, 56, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Dark", NULL, NULL },
4727 { jwin_check_proc, 144, 66, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Items", NULL, NULL },
4728 // 11
4729 { jwin_button_proc, 42, 110, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
4730 { jwin_button_proc, 122, 110, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
4731 { jwin_check_proc, 16, 88, 97, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Save to Image", NULL, NULL },
4732 // 14
4733 { jwin_radio_proc, 16, 66, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void*)"2x - 8192x2816", NULL, NULL },
4734 { jwin_radio_proc, 16, 76, 97, 9, vc(14), vc(1), 0, 0, 0, 0, (void*)"4x - 16384x5632", NULL, NULL },
4735 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
4736 };
4737
4738 int32_t load_the_map(bool skipmenu)
4739 {
4740 static int32_t res = 0;
4741 static int32_t flags = cDEBUG;
4742
4743 loadmap_dlg[0].dp2 = get_zc_font(font_lfont);
4744 loadmap_dlg[3].flags = (res==2) ? D_SELECTED : 0;
4745 loadmap_dlg[4].flags = (res==1) ? D_SELECTED : 0;
4746 loadmap_dlg[5].flags = (res==0) ? D_SELECTED : 0;
4747 loadmap_dlg[7].flags = (flags&cWALK) ? D_SELECTED : 0;
4748 loadmap_dlg[8].flags = (flags&cFLAGS) ? D_SELECTED : 0;
4749 loadmap_dlg[9].flags = (flags&cNODARK) ? 0 : D_SELECTED;
4750 loadmap_dlg[10].flags = (flags&cNOITEM) ? 0 : D_SELECTED;
4751 loadmap_dlg[13].flags = 0;
4752 loadmap_dlg[14].flags = (res==3) ? D_SELECTED : 0;
4753 loadmap_dlg[15].flags = (res==4) ? D_SELECTED : 0;
4754
4755 if(!skipmenu)
4756 {
4757 large_dialog(loadmap_dlg);
4758
4759 if (do_zqdialog(loadmap_dlg, 11, true) != 11)
4760 {
4761 return 1;
4762 }
4763
4764 flags = cDEBUG;
4765
4766 if(loadmap_dlg[3].flags&D_SELECTED) res=2;
4767
4768 if(loadmap_dlg[4].flags&D_SELECTED) res=1;
4769
4770 if(loadmap_dlg[5].flags&D_SELECTED) res=0;
4771
4772 if(loadmap_dlg[7].flags&D_SELECTED) flags|=cWALK;
4773
4774 if(loadmap_dlg[8].flags&D_SELECTED) flags|=cFLAGS;
4775
4776 if(!(loadmap_dlg[9].flags&D_SELECTED)) flags|=cNODARK;
4777
4778 if(!(loadmap_dlg[10].flags&D_SELECTED)) flags|=cNOITEM;
4779
4780 if(loadmap_dlg[14].flags&D_SELECTED) res=3;
4781
4782 if(loadmap_dlg[15].flags&D_SELECTED) res=4;
4783 }
4784
4785 int32_t bw = (256*16)>>res;
4786 int32_t bh = (176*8)>>res;
4787 int32_t sw = 256>>res;
4788 int32_t sh = 176>>res;
4789 if(res>2)
4790 {
4791 bw = (256*16)<<(res-2);
4792 bh = (176*8)<<(res-2);
4793 sw = 256<<(res-2);
4794 sh = 176<<(res-2);
4795 }
4796
4797 mapview_open(flags, sw, sh, bw, bh);
4798
4799 vp_showpal = false;
4800 get_bw(picpal,pblack,pwhite);
4801 mapx = mapy = 0;
4802 mapscale = 1;
4803 imagepath[0] = 0;
4804
4805 if(loadmap_dlg[13].flags & D_SELECTED) saveMapAsImage(mapview_get_rti()->bitmap);
4806
4807 memcpy(mappal,RAMpal,sizeof(RAMpal));
4808
4809 return 0;
4810 }
4811
4812 int32_t onViewMap()
4813 {
4814 return onViewMapEx(false);
4815 }
4816 int32_t onViewMapEx(bool skipmenu)
4817 {
4818 int32_t temp_aligns=ShowMisalignments;
4819 ShowMisalignments=0;
4820 launchPicViewer(&bmap,mappal,mapx, mapy, mapscale,true,skipmenu);
4821 ShowMisalignments=temp_aligns;
4822 return D_O_K;
4823 }
4824
4825 static const char *mazedirstr[4] = {"North","South","West","East"};
4826 char _pathstr[40]="North,North,North,North";
4827
4828 char *pathstr(byte path[])
4829 {
4830 sprintf(_pathstr,"%s,%s,%s,%s",mazedirstr[path[0]],mazedirstr[path[1]],
4831 mazedirstr[path[2]],mazedirstr[path[3]]);
4832 return _pathstr;
4833 }
4834
4835 char _ticksstr[32]="99.99 seconds";
4836
4837 char *ticksstr(int32_t tics)
4838 {
4839 int32_t mins=tics/(60*60);
4840 tics=tics-(mins*60*60);
4841 int32_t secs=tics/60;
4842 tics=tics-(secs*60);
4843 tics=tics*100/60;
4844
4845 if(mins>0)
4846 {
4847 sprintf(_ticksstr,"%d:%02d.%02d",mins, secs, tics);
4848 }
4849 else
4850 {
4851 sprintf(_ticksstr,"%d.%02d seconds",secs, tics);
4852 }
4853
4854 return _ticksstr;
4855 }
4856
4857 ZC_FORMAT_PRINTF(7, 8)
4858 void textprintf_disabled(BITMAP *bmp, AL_CONST FONT *f, int32_t x, int32_t y, int32_t color_hl, int32_t color_sh, AL_CONST char *format, ...)
4859 {
4860 char buf[512];
4861 va_list ap;
4862 ASSERT(bmp);
4863 ASSERT(f);
4864 ASSERT(format);
4865
4866 va_start(ap, format);
4867 vsnprintf(buf, sizeof(buf), format, ap);
4868 va_end(ap);
4869
4870
4871 textout_ex(bmp, f, buf, x+1, y+1, color_hl, -1);
4872
4873 textout_ex(bmp, f, buf, x, y, color_sh, -1);
4874 }
4875
4876 ZC_FORMAT_PRINTF(7, 8)
4877 void textprintf_centre_disabled(BITMAP *bmp, AL_CONST FONT *f, int32_t x, int32_t y, int32_t color_hl, int32_t color_sh, AL_CONST char *format, ...)
4878 {
4879 char buf[512];
4880 va_list ap;
4881 ASSERT(bmp);
4882 ASSERT(f);
4883 ASSERT(format);
4884
4885 va_start(ap, format);
4886 vsnprintf(buf, sizeof(buf), format, ap);
4887 va_end(ap);
4888
4889 textout_centre_ex(bmp, f, buf, x+1, y+1, color_hl, -1);
4890 textout_centre_ex(bmp, f, buf, x, y, color_sh, -1);
4891 }
4892
4893 void draw_sqr_frame(size_and_pos const& sqr)
4894 {
4895 jwin_draw_frame(screen,sqr.x,sqr.y,sqr.tw(),sqr.th(),FR_DEEP);
4896 }
4897 void draw_sqr_icon(size_and_pos const& sqr, BITMAP* icon)
4898 {
4899 stretch_blit(icon, screen, 0, 0, 16, 16, sqr.x+2, sqr.y+2, sqr.tw()-4, sqr.th()-4);
4900 }
4901 void draw_sqr_nums(size_and_pos const& sqr, FONT* f, bool center, int num)
4902 {
4903 if(center)
4904 textprintf_centre_ex(screen,f,sqr.x+txtoffs_single.x,sqr.y+txtoffs_single.y,jwin_pal[jcBOXFG],-1,"%d",num);
4905 else
4906 textprintf_ex(screen,f,sqr.x+txtoffs_single.x,sqr.y+txtoffs_single.y,jwin_pal[jcBOXFG],-1,"%d",num);
4907 }
4908 void draw_sqr_nums(size_and_pos const& sqr, FONT* f, bool center, int num1, int num2)
4909 {
4910 if(center)
4911 {
4912 textprintf_centre_ex(screen,f,sqr.x+txtoffs_double_1.x,sqr.y+txtoffs_double_1.y,jwin_pal[jcBOXFG],-1,"%d",num1);
4913 textprintf_centre_ex(screen,f,sqr.x+txtoffs_double_2.x,sqr.y+txtoffs_double_2.y,jwin_pal[jcBOXFG],-1,"%d",num2);
4914 }
4915 else
4916 {
4917 textprintf_ex(screen,f,sqr.x+txtoffs_double_1.x,sqr.y+txtoffs_double_1.y,jwin_pal[jcBOXFG],-1,"%d",num1);
4918 textprintf_ex(screen,f,sqr.x+txtoffs_double_2.x,sqr.y+txtoffs_double_2.y,jwin_pal[jcBOXFG],-1,"%d",num2);
4919 }
4920 }
4921 void draw_sqr_btn(size_and_pos const& sqr, const char* txt, int flags, FONT* f = nullptr)
4922 {
4923 if(sqr.x < 0) return;
4924 FONT* tfont = font;
4925 if(f)
4926 font = f;
4927 draw_text_button(screen, sqr.x, sqr.y, sqr.tw(), sqr.th(), txt, 0, 0, flags, true);
4928 font = tfont;
4929 }
4930 void draw_sqr_btn(size_and_pos const& sqr, int icon, int flags, FONT* f = nullptr)
4931 {
4932 if(sqr.x < 0) return;
4933 FONT* tfont = font;
4934 if(f)
4935 font = f;
4936 draw_icon_button(screen, sqr.x, sqr.y, sqr.tw(), sqr.th(), icon, 0, 0, flags, true);
4937 font = tfont;
4938 }
4939
4940 void drawpanel()
4941 {
4942 mapscr *scr=Map.CurrScr();
4943 int32_t NextCombo = combobuf[Combo].nextcombo;
4944 int32_t NextCSet = combobuf[Combo].nextcset;
4945 if(combobuf[Combo].animflags & AF_CYCLEUNDERCOMBO)
4946 {
4947 NextCombo = scr->undercombo;
4948 NextCSet = scr->undercset;
4949 }
4950 if(combobuf[Combo].animflags & AF_CYCLENOCSET)
4951 NextCSet = CSet;
4952
4953 FONT* tfont = font;
4954 if(prv_mode)
4955 {
4956 jwin_draw_frame(screen,0,preview_panel.y,preview_panel.x+preview_panel.w, preview_panel.h, FR_WIN);
4957 rectfill(screen,preview_panel.x,preview_panel.y+2,preview_panel.x+preview_panel.w-3,preview_panel.y+preview_panel.h-3,jwin_pal[jcBOX]);
4958 }
4959 else
4960 {
4961 auto& sqr = main_panel;
4962 rectfill(screen,sqr.x,sqr.y,sqr.x+sqr.w-1,sqr.y+sqr.h-1, jwin_pal[jcBOX]);
4963 refresh(rSCRMAP);
4964 jwin_draw_frame(screen,sqr.x,sqr.y,sqr.w,sqr.h, FR_WIN);
4965
4966 font = get_custom_font(CFONT_GUI);
4967 draw_sqr_btn(squarepanel_swap_btn, "SWP", 0);
4968 if(compact_square_panels)
4969 {
4970 textprintf_centre_ex(screen,font,squarepanel_up_btn.cx(),squarepanel_up_btn.y-text_height(font)-2,jwin_pal[jcBOXFG],-1,"%d",compact_active_panel);
4971 draw_sqr_btn(squarepanel_up_btn, BTNICON_ARROW_UP, 0);
4972 draw_sqr_btn(squarepanel_down_btn, BTNICON_ARROW_DOWN, 0);
4973 }
4974 font = tfont;
4975
4976 FONT* sqr_text_font = (is_compact && compact_square_panels) ? get_custom_font(CFONT_GUI) : font;
4977 //Item:
4978 if(itemsqr_pos.x > -1)
4979 {
4980 draw_sqr_frame(itemsqr_pos);
4981 if(scr->hasitem)
4982 {
4983 rectfill(screen,itemsqr_pos.x+2,itemsqr_pos.y+2,itemsqr_pos.x+itemsqr_pos.tw()-3,itemsqr_pos.y+itemsqr_pos.th()-3,0);
4984 overtile16_scale(screen, itemsbuf[scr->item].tile,itemsqr_pos.x+2,itemsqr_pos.y+2,itemsbuf[scr->item].csets&15,0,itemsqr_pos.tw()-4,itemsqr_pos.th()-4);
4985 }
4986 else draw_sqr_icon(itemsqr_pos, icon_bmp[0][coord_frame]);
4987 draw_sqr_nums(itemsqr_pos, sqr_text_font, panel_align == 1, scr->itemx, scr->itemy);
4988 }
4989 //Flag:
4990 if(flagsqr_pos.x > -1)
4991 {
4992 draw_sqr_frame(flagsqr_pos);
4993 draw_sqr_icon(flagsqr_pos,flag_bmp[Flag%16][coord_frame]);
4994 draw_sqr_nums(flagsqr_pos, sqr_text_font, panel_align == 1, Flag);
4995 }
4996
4997 //Stairs:
4998 if(stairsqr_pos.x > -1)
4999 {
5000 draw_sqr_frame(stairsqr_pos);
5001 draw_sqr_icon(stairsqr_pos,icon_bmp[1][coord_frame]);
5002 draw_sqr_nums(stairsqr_pos, sqr_text_font, panel_align == 1, scr->stairx, scr->stairy);
5003 }
5004
5005 //Green arrival square:
5006 bool disabled_arrival = get_qr(qr_NOARRIVALPOINT);
5007 if(warparrival_pos.x > -1)
5008 {
5009 draw_sqr_frame(warparrival_pos);
5010 BITMAP* icon = icon_bmp[2][coord_frame];
5011 if(disabled_arrival)
5012 {
5013 icon = create_bitmap_ex(8,16,16);
5014 blit(icon_bmp[2][0], icon, 0, 0, 0, 0, 16, 16);
5015 replColor(icon, 0xE7, 0xEA, 0xEA, false);
5016 replColor(icon, 0xE8, 0xE2, 0xE2, false);
5017 }
5018
5019 draw_sqr_icon(warparrival_pos, icon);
5020 draw_sqr_nums(warparrival_pos, sqr_text_font, panel_align == 1, scr->warparrivalx, scr->warparrivaly);
5021
5022 if(disabled_arrival)
5023 destroy_bitmap(icon);
5024 }
5025
5026 //Blue return squares:
5027 for(int32_t i=0; i<4; i++)
5028 {
5029 if(warpret_pos[i].x < 0) continue;
5030 draw_sqr_frame(warpret_pos[i]);
5031 draw_sqr_icon(warpret_pos[i], icon_bmp[ICON_BMP_RETURN_A+i][coord_frame]);
5032 draw_sqr_nums(warpret_pos[i], sqr_text_font, panel_align == 1, scr->warpreturnx[i], scr->warpreturny[i]);
5033 }
5034
5035 // Enemies
5036 auto& ep = enemy_prev_pos;
5037 if(ep.x > -1)
5038 {
5039 if(ep.fw > -1)
5040 {
5041 rectfill(screen, ep.x, ep.y, ep.x+ep.tw()-1,ep.y+ep.th()-1,vc(0));
5042 rectfill(screen, ep.x+ep.fw, ep.y+ep.fh, ep.x+ep.tw()-1, ep.y+ep.th()-1, jwin_pal[jcBOX]);
5043 jwin_draw_frag_frame(screen, ep.x, ep.y, ep.tw(), ep.th(), ep.fw, ep.fh, FR_DEEP);
5044 }
5045 else
5046 {
5047 rectfill(screen, ep.x, ep.y, ep.x+ep.tw()-1,ep.y+ep.th()-1,vc(0));
5048 draw_sqr_frame(ep);
5049 }
5050 for(int32_t i=0; i< 10 && Map.CurrScr()->enemy[i]!=0; i++)
5051 {
5052 int32_t id = Map.CurrScr()->enemy[i];
5053 int32_t tile = get_qr(qr_NEWENEMYTILES) ? guysbuf[id].e_tile : guysbuf[id].tile;
5054 int32_t cset = guysbuf[id].cset;
5055 auto& sqr = ep.subsquare(i);
5056 if(tile)
5057 overtile16_scale(screen, tile+efrontfacingtile(id),sqr.x,sqr.y,cset,0,sqr.tw(),sqr.th());
5058 }
5059 }
5060 }
5061 font = tfont;
5062 }
5063
5064 void show_screen_error(const char *str, int32_t i, int32_t c)
5065 {
5066 rectfill(screen, screrrorpos.x-text_length(get_zc_font(font_lfont_l),str),screrrorpos.y-(i*16),screrrorpos.x,screrrorpos.y-((i-1)*16)-4,vc(0));
5067 textout_shadowed_ex(screen,get_zc_font(font_lfont_l), str,screrrorpos.x-text_length(get_zc_font(font_lfont_l),str),screrrorpos.y-(i*16),c,vc(0),-1);
5068 }
5069
5070 void tile_warp_notification(int32_t which, char *buf)
5071 {
5072 char letter = 'A'+which;
5073
5074 switch(Map.CurrScr()->tilewarptype[which])
5075 {
5076 case wtCAVE:
5077 sprintf(buf,"Tile Warp %c: Cave/Item Cellar",letter);
5078 break;
5079
5080 default:
5081 {
5082 char buf2[30];
5083
5084 if(strlen(DMaps[Map.CurrScr()->tilewarpdmap[which]].name)==0)
5085 {
5086 sprintf(buf2,"%d",Map.CurrScr()->tilewarpdmap[which]);
5087 }
5088 else
5089 sprintf(buf2,"%d-%s",Map.CurrScr()->tilewarpdmap[which],DMaps[Map.CurrScr()->tilewarpdmap[which]].name);
5090
5091 sprintf(buf,"Tile Warp %c: %s, %02X", letter, buf2, Map.CurrScr()->tilewarpscr[which]);
5092 break;
5093 }
5094
5095 case wtNOWARP:
5096 sprintf(buf,"Tile Warp %c: Cancel Warp", letter);
5097 break;
5098 }
5099 }
5100
5101 void side_warp_notification(int32_t which, int32_t dir, char *buf)
5102 {
5103 char letter = 'A'+which;
5104 char buf3[16];
5105
5106 if(dir==0 && Map.CurrScr()->timedwarptics)
5107 sprintf(buf3,"%s, Timed",mazedirstr[dir]);
5108 else if(dir==4)
5109 sprintf(buf3,"Timed");
5110 else
5111 strcpy(buf3, mazedirstr[dir]);
5112
5113 switch(Map.CurrScr()->sidewarptype[which])
5114 {
5115 case wtCAVE:
5116 sprintf(buf,"Side Warp %c (%s): Cave/Item Cellar",letter, buf3);
5117 break;
5118
5119 default:
5120 {
5121 // Destination DMap name
5122 if(strlen(DMaps[Map.CurrScr()->sidewarpdmap[which]].name)==0)
5123 {
5124 sprintf(buf,"Side Warp %c (%s): %d, %02X", letter, buf3, Map.CurrScr()->sidewarpdmap[which], Map.CurrScr()->sidewarpscr[which]);
5125 }
5126 else
5127 sprintf(buf,"Side Warp %c (%s): %d-%s, %02X", letter, buf3, Map.CurrScr()->sidewarpdmap[which],DMaps[Map.CurrScr()->sidewarpdmap[which]].name, Map.CurrScr()->sidewarpscr[which]);
5128
5129 break;
5130 }
5131
5132 case wtNOWARP:
5133 sprintf(buf,"Side Warp %c (%s): Cancel Warp", letter, buf3);
5134 break;
5135 }
5136 }
5137
5138 static bool arrowcursor = true; // Used by combo aliases and Combo Brush cursors. -L
5139
5140 void xout(BITMAP* dest, int x, int y, int x2, int y2, int c, int bgc = -1)
5141 {
5142 //BG Fill
5143 if(bgc > -1)
5144 rectfill(dest, x, y, x2, y2, bgc);
5145 ++x; ++y; --x2; --y2;
5146 //Border
5147 safe_rect(dest, x, y, x2, y2, c);
5148 //line(dest, x, y, x2, y, c);
5149 //line(dest, x, y, x, y2, c);
5150 //X
5151 line(dest, x, y, x2, y2, c);
5152 line(dest, x, y2, x2, y, c);
5153 }
5154
5155 void put_autocombo_engravings(BITMAP* dest, combo_auto const& ca, bool selected, int32_t x, int32_t y, int32_t scale)
5156 {
5157 if (!ca.valid())
5158 {
5159 if (ca.getDisplay() > 0)
5160 put_engraving(dest, x, y, 15, scale);
5161 }
5162 else
5163 {
5164 if (ca.getType() == AUTOCOMBO_Z4 || ca.getType() == AUTOCOMBO_DOR)
5165 {
5166 byte hei = vbound(ca.getArg() + 1, 1, 9);
5167 if (selected)
5168 hei = vbound(cauto_height, 1, 9);
5169 put_engraving(dest, x, y, 15 - hei, scale);
5170 }
5171 }
5172 }
5173
5174 static void draw_screenunit_map_screen2(VisibleScreen visible_screen)
5175 {
5176 BITMAP* screen_bitmap = screen;
5177
5178 int num_screens_to_draw = Map.getViewSize();
5179 int screen = visible_screen.screen;
5180 int xoff = visible_screen.xoff;
5181 int yoff = visible_screen.yoff;
5182
5183 mapscr* scr = visible_screen.scr;
5184 if (!layers_valid(scr))
5185 fix_layers(scr, true);
5186
5187 clear_to_color(mapscreenbmp, 0);
5188
5189 int view_scr_x = Map.getViewScr() % 16;
5190 int view_scr_y = Map.getViewScr() / 16;
5191 int scr_x = screen % 16;
5192 int scr_y = screen / 16;
5193 int edge_xoff = 0, edge_yoff = 0;
5194 if(showedges)
5195 {
5196 if (scr_x == view_scr_x)
5197 edge_xoff = 16;
5198 else
5199 xoff -= 16;
5200
5201 if (scr_y == view_scr_y)
5202 edge_yoff = 16;
5203 else
5204 yoff -= 16;
5205 }
5206
5207 // TODO: should be better to move this out of draw_screenunit_map_screen.
5208 if (showedges && screen < 128)
5209 {
5210 bool peek_above = scr_y == view_scr_y;
5211 bool peek_below = scr_y == view_scr_y + num_screens_to_draw - 1;
5212 bool peek_left = scr_x == view_scr_x;
5213 bool peek_right = scr_x == view_scr_x + num_screens_to_draw - 1;
5214
5215 int right_col = 272 - (num_screens_to_draw > 1 ? 16 : 0);
5216 int bottom_row = 192 - (num_screens_to_draw > 1 ? 16 : 0);
5217
5218 //not the first row of screens
5219 if (peek_above)
5220 {
5221 if(screen>15 && !NoScreenPreview)
5222 {
5223 Map.drawrow(mapscreenbmp, edge_xoff, 0, Flags, 160, -1, screen-16);
5224 }
5225 else
5226 {
5227 Map.drawstaticrow(mapscreenbmp, edge_xoff, 0);
5228 }
5229 }
5230
5231 //not the last row of screens
5232 if (peek_below)
5233 {
5234 if(screen + 16 < 0x80 && !NoScreenPreview)
5235 {
5236 Map.drawrow(mapscreenbmp, edge_xoff, bottom_row, Flags, 0, -1, screen+16);
5237 }
5238 else
5239 {
5240 Map.drawstaticrow(mapscreenbmp, edge_xoff, bottom_row);
5241 }
5242 }
5243
5244 //not the first column of screens
5245 if (peek_left)
5246 {
5247 if(screen&0x0F && !NoScreenPreview)
5248 {
5249 Map.drawcolumn(mapscreenbmp, 0, edge_yoff, Flags, 15, -1, screen-1);
5250 }
5251 else
5252 {
5253 Map.drawstaticcolumn(mapscreenbmp, 0, edge_yoff);
5254 }
5255 }
5256
5257 //not the last column of screens
5258 if (peek_right)
5259 {
5260 if((screen&0x0F)<15 && !NoScreenPreview)
5261 {
5262 Map.drawcolumn(mapscreenbmp, right_col, edge_yoff, Flags, 0, -1, screen+1);
5263 }
5264 else
5265 {
5266 Map.drawstaticcolumn(mapscreenbmp, right_col, edge_yoff);
5267 }
5268 }
5269
5270 //not the first row or first column of screens
5271 if (peek_above && peek_left)
5272 {
5273 if((screen>15)&&(screen&0x0F) && !NoScreenPreview)
5274 {
5275 Map.drawblock(mapscreenbmp, 0, 0, Flags, 175, -1, screen-17);
5276 }
5277 else
5278 {
5279 Map.drawstaticblock(mapscreenbmp, 0, 0);
5280 }
5281 }
5282
5283 //not the first row or last column of screens
5284 if (peek_above && peek_right)
5285 {
5286 if((screen>15)&&((screen&0x0F)<15) && !NoScreenPreview)
5287 {
5288 Map.drawblock(mapscreenbmp, right_col, 0, Flags, 160, -1, screen-15);
5289 }
5290 else
5291 {
5292 Map.drawstaticblock(mapscreenbmp, right_col, 0);
5293 }
5294 }
5295
5296 //not the last row or first column of screens
5297 if (peek_below && peek_left)
5298 {
5299 if((screen<112)&&(screen&0x0F) && !NoScreenPreview)
5300 {
5301 Map.drawblock(mapscreenbmp, 0, bottom_row, Flags, 15, -1, screen+15);
5302 }
5303 else
5304 {
5305 Map.drawstaticblock(mapscreenbmp, 0, bottom_row);
5306 }
5307 }
5308
5309 //not the last row or last column of screens
5310 if (peek_below && peek_right)
5311 {
5312 if((screen<112)&&((screen&0x0F)<15) && !NoScreenPreview)
5313 {
5314 Map.drawblock(mapscreenbmp, right_col, bottom_row, Flags, 0, -1, screen+17);
5315 }
5316 else
5317 {
5318 Map.drawstaticblock(mapscreenbmp, right_col, bottom_row);
5319 }
5320 }
5321 }
5322
5323 if (ShowSquares && Map.getViewSize() < 4)
5324 {
5325 if(scr->stairx || scr->stairy)
5326 {
5327 int32_t x1 = scr->stairx+edge_xoff;
5328 int32_t y1 = scr->stairy+edge_yoff;
5329 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,vc(14));
5330 }
5331
5332 if(scr->warparrivalx || scr->warparrivaly)
5333 {
5334 int32_t x1 = scr->warparrivalx +edge_xoff;
5335 int32_t y1 = scr->warparrivaly +edge_yoff;
5336 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,vc(10));
5337 }
5338
5339 for(int32_t i=0; i<4; i++) if(scr->warpreturnx[i] || scr->warpreturny[i])
5340 {
5341 int32_t x1 = scr->warpreturnx[i]+edge_xoff;
5342 int32_t y1 = scr->warpreturny[i]+edge_yoff;
5343 int32_t clr = vc(9);
5344
5345 if(FlashWarpSquare==i)
5346 {
5347 if(!FlashWarpClk)
5348 FlashWarpSquare=-1;
5349 else if(!(--FlashWarpClk%3))
5350 clr = vc(15);
5351 }
5352
5353 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,clr);
5354 }
5355 }
5356
5357 if(ShowFFCs)
5358 {
5359 mapscr* ffscr = prv_mode ? Map.get_prvscr() : scr;
5360 int num_ffcs = ffscr->numFFC();
5361 for(int32_t i=num_ffcs-1; i>=0; i--)
5362 {
5363 ffcdata& ff = ffscr->ffcs[i];
5364 if(ff.data !=0 && (ff.layer >= CurrentLayer || (ff.flags&ffc_overlay)))
5365 {
5366 auto x = ff.x+edge_xoff;
5367 auto y = ff.y+edge_yoff;
5368 safe_rect(mapscreenbmp, x+0, y+0, x+ff.txsz*16-1, y+ff.tysz*16-1, vc(12));
5369 }
5370 }
5371 }
5372
5373 if(num_screens_to_draw == 1 && !(Flags&cDEBUG) && pixeldb==1)
5374 {
5375 for(int32_t j=168; j<176; j++)
5376 {
5377 for(int32_t i=0; i<256; i++)
5378 {
5379 if(((i^j)&1)==0)
5380 {
5381 putpixel(mapscreenbmp,edge_xoff+i,
5382 edge_yoff+j,vc(blackout_color));
5383 }
5384 }
5385 }
5386 }
5387
5388 int w = mapscreenbmp->w * mapscreen_single_scale;
5389 int h = mapscreenbmp->h * mapscreen_single_scale;
5390 stretch_blit(mapscreenbmp, screen_bitmap, 0, 0, mapscreenbmp->w, mapscreenbmp->h, mapscreen_x + xoff, mapscreen_y + yoff, w, h);
5391 }
5392
5393 static void draw_screenunit_map_screen(VisibleScreen visible_screen)
5394 {
5395 BITMAP* screen_bitmap = screen;
5396
5397 if (HighQualityScreenRendering) return draw_screenunit_map_screen2(visible_screen);
5398
5399 int num_screens_to_draw = Map.getViewSize();
5400 int screen = visible_screen.screen;
5401 int xoff = visible_screen.xoff;
5402 int yoff = visible_screen.yoff;
5403
5404 mapscr* scr = visible_screen.scr;
5405 if (!layers_valid(scr))
5406 fix_layers(scr, true);
5407
5408 clear_to_color(mapscreenbmp, jwin_pal[jcBOX]);
5409 if (LayerDitherBG > -1)
5410 {
5411 if (LayerDitherSz > 0)
5412 ditherblit(mapscreenbmp, nullptr, vc(LayerDitherBG), dithChecker, LayerDitherSz);
5413 else
5414 clear_to_color(mapscreenbmp, vc(LayerDitherBG));
5415 }
5416
5417 int view_scr_x = Map.getViewScr() % 16;
5418 int view_scr_y = Map.getViewScr() / 16;
5419 int scr_x = screen % 16;
5420 int scr_y = screen / 16;
5421 int edge_xoff = 0, edge_yoff = 0;
5422 if(showedges)
5423 {
5424 if (scr_x == view_scr_x)
5425 edge_xoff = 16;
5426 else
5427 xoff -= 16;
5428
5429 if (scr_y == view_scr_y)
5430 edge_yoff = 16;
5431 else
5432 yoff -= 16;
5433 }
5434
5435 combotile_add_x = mapscreen_x + xoff;
5436 combotile_add_y = mapscreen_y + yoff;
5437 combotile_mul_x = mapscreen_single_scale;
5438 combotile_mul_y = mapscreen_single_scale;
5439 Map.draw(mapscreenbmp, scr_x == view_scr_x && showedges ? 16 : 0, scr_y == view_scr_y && showedges ? 16 : 0, Flags, Map.getCurrMap(), screen, ActiveLayerHighlight ? CurrentLayer : -1);
5440 combotile_add_x = 0;
5441 combotile_add_y = 0;
5442 combotile_mul_x = 1;
5443 combotile_mul_y = 1;
5444
5445 // TODO: should be better to move this out of draw_screenunit_map_screen.
5446 if (showedges && screen < 128)
5447 {
5448 bool peek_above = scr_y == view_scr_y;
5449 bool peek_below = scr_y == view_scr_y + num_screens_to_draw - 1;
5450 bool peek_left = scr_x == view_scr_x;
5451 bool peek_right = scr_x == view_scr_x + num_screens_to_draw - 1;
5452
5453 int right_col = 272 - (num_screens_to_draw > 1 ? 16 : 0);
5454 int bottom_row = 192 - (num_screens_to_draw > 1 ? 16 : 0);
5455
5456 //not the first row of screens
5457 if (peek_above)
5458 {
5459 if(screen>15 && !NoScreenPreview)
5460 {
5461 Map.drawrow(mapscreenbmp, edge_xoff, 0, Flags, 160, -1, screen-16);
5462 }
5463 else
5464 {
5465 Map.drawstaticrow(mapscreenbmp, edge_xoff, 0);
5466 }
5467 }
5468
5469 //not the last row of screens
5470 if (peek_below)
5471 {
5472 if(screen + 16 < 0x80 && !NoScreenPreview)
5473 {
5474 Map.drawrow(mapscreenbmp, edge_xoff, bottom_row, Flags, 0, -1, screen+16);
5475 }
5476 else
5477 {
5478 Map.drawstaticrow(mapscreenbmp, edge_xoff, bottom_row);
5479 }
5480 }
5481
5482 //not the first column of screens
5483 if (peek_left)
5484 {
5485 if(screen&0x0F && !NoScreenPreview)
5486 {
5487 Map.drawcolumn(mapscreenbmp, 0, edge_yoff, Flags, 15, -1, screen-1);
5488 }
5489 else
5490 {
5491 Map.drawstaticcolumn(mapscreenbmp, 0, edge_yoff);
5492 }
5493 }
5494
5495 //not the last column of screens
5496 if (peek_right)
5497 {
5498 if((screen&0x0F)<15 && !NoScreenPreview)
5499 {
5500 Map.drawcolumn(mapscreenbmp, right_col, edge_yoff, Flags, 0, -1, screen+1);
5501 }
5502 else
5503 {
5504 Map.drawstaticcolumn(mapscreenbmp, right_col, edge_yoff);
5505 }
5506 }
5507
5508 //not the first row or first column of screens
5509 if (peek_above && peek_left)
5510 {
5511 if((screen>15)&&(screen&0x0F) && !NoScreenPreview)
5512 {
5513 Map.drawblock(mapscreenbmp, 0, 0, Flags, 175, -1, screen-17);
5514 }
5515 else
5516 {
5517 Map.drawstaticblock(mapscreenbmp, 0, 0);
5518 }
5519 }
5520
5521 //not the first row or last column of screens
5522 if (peek_above && peek_right)
5523 {
5524 if((screen>15)&&((screen&0x0F)<15) && !NoScreenPreview)
5525 {
5526 Map.drawblock(mapscreenbmp, right_col, 0, Flags, 160, -1, screen-15);
5527 }
5528 else
5529 {
5530 Map.drawstaticblock(mapscreenbmp, right_col, 0);
5531 }
5532 }
5533
5534 //not the last row or first column of screens
5535 if (peek_below && peek_left)
5536 {
5537 if((screen<112)&&(screen&0x0F) && !NoScreenPreview)
5538 {
5539 Map.drawblock(mapscreenbmp, 0, bottom_row, Flags, 15, -1, screen+15);
5540 }
5541 else
5542 {
5543 Map.drawstaticblock(mapscreenbmp, 0, bottom_row);
5544 }
5545 }
5546
5547 //not the last row or last column of screens
5548 if (peek_below && peek_right)
5549 {
5550 if((screen<112)&&((screen&0x0F)<15) && !NoScreenPreview)
5551 {
5552 Map.drawblock(mapscreenbmp, right_col, bottom_row, Flags, 0, -1, screen+17);
5553 }
5554 else
5555 {
5556 Map.drawstaticblock(mapscreenbmp, right_col, bottom_row);
5557 }
5558 }
5559 }
5560
5561 if (ShowSquares && Map.getViewSize() < 4)
5562 {
5563 if(scr->stairx || scr->stairy)
5564 {
5565 int32_t x1 = scr->stairx+edge_xoff;
5566 int32_t y1 = scr->stairy+edge_yoff;
5567 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,vc(14));
5568 }
5569
5570 if(scr->warparrivalx || scr->warparrivaly)
5571 {
5572 int32_t x1 = scr->warparrivalx +edge_xoff;
5573 int32_t y1 = scr->warparrivaly +edge_yoff;
5574 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,vc(10));
5575 }
5576
5577 for(int32_t i=0; i<4; i++) if(scr->warpreturnx[i] || scr->warpreturny[i])
5578 {
5579 int32_t x1 = scr->warpreturnx[i]+edge_xoff;
5580 int32_t y1 = scr->warpreturny[i]+edge_yoff;
5581 int32_t clr = vc(9);
5582
5583 if(FlashWarpSquare==i)
5584 {
5585 if(!FlashWarpClk)
5586 FlashWarpSquare=-1;
5587 else if(!(--FlashWarpClk%3))
5588 clr = vc(15);
5589 }
5590
5591 safe_rect(mapscreenbmp,x1,y1,x1+15,y1+15,clr);
5592 }
5593 }
5594
5595 if(ShowFFCs)
5596 {
5597 mapscr* ffscr = prv_mode ? Map.get_prvscr() : scr;
5598 int num_ffcs = ffscr->numFFC();
5599 for(int32_t i=num_ffcs-1; i>=0; i--)
5600 {
5601 ffcdata& ff = ffscr->ffcs[i];
5602 if(ff.data !=0 && (ff.layer >= CurrentLayer || (!CurrentLayer && ff.layer < 0) || (ff.flags&ffc_overlay)))
5603 {
5604 auto x = ff.x+edge_xoff;
5605 auto y = ff.y+edge_yoff;
5606 safe_rect(mapscreenbmp, x+0, y+0, x+ff.txsz*16-1, y+ff.tysz*16-1, vc(12));
5607 }
5608 }
5609 }
5610
5611 if(num_screens_to_draw == 1 && !(Flags&cDEBUG) && pixeldb==1)
5612 {
5613 for(int32_t j=168; j<176; j++)
5614 {
5615 for(int32_t i=0; i<256; i++)
5616 {
5617 if(((i^j)&1)==0)
5618 {
5619 putpixel(mapscreenbmp,edge_xoff+i,
5620 edge_yoff+j,vc(blackout_color));
5621 }
5622 }
5623 }
5624 }
5625
5626 int w = mapscreenbmp->w * mapscreen_single_scale;
5627 int h = mapscreenbmp->h * mapscreen_single_scale;
5628 stretch_blit(mapscreenbmp, screen_bitmap, 0, 0, mapscreenbmp->w, mapscreenbmp->h, mapscreen_x + xoff, mapscreen_y + yoff, w, h);
5629 }
5630
5631 static void draw_static_pos(const size_and_pos& sqr)
5632 {
5633 draw_static(screen, sqr.x, sqr.y, sqr.w, sqr.h);
5634 }
5635
5636 void draw_screenunit(int32_t unit, int32_t flags)
5637 {
5638 FONT* tfont = font;
5639 switch(unit)
5640 {
5641 case rSCRMAP:
5642 {
5643 mmap_mark_active();
5644
5645 size_and_pos *mini_sqr = &minimap;
5646 size_and_pos *real_mini_sqr = &real_minimap;
5647
5648 if(zoomed_minimap)
5649 {
5650 mini_sqr = &minimap_zoomed;
5651 real_mini_sqr = &real_minimap_zoomed;
5652 }
5653
5654 auto txt_x = real_mini_sqr->x+2+8*real_mini_sqr->xscale;
5655 auto txt_y = real_mini_sqr->y+2+8*real_mini_sqr->yscale;
5656
5657 rectfill(screen, mini_sqr->x-1, mini_sqr->y-2,mini_sqr->x+mini_sqr->w-1,mini_sqr->y+mini_sqr->h-1,jwin_pal[jcBOX]);
5658 if(zoomed_minimap)
5659 jwin_draw_frame(screen, mini_sqr->x-1, mini_sqr->y-2,mini_sqr->w,mini_sqr->h,FR_WIN);
5660 jwin_draw_minimap_frame(screen,real_mini_sqr->x,real_mini_sqr->y,real_mini_sqr->tw(), real_mini_sqr->th(), real_mini_sqr->xscale, FR_DEEP);
5661
5662 if(Map.getCurrMap()<Map.getMapCount())
5663 {
5664 for(int32_t i=0; i<MAPSCRS; i++)
5665 {
5666 auto& sqr = real_mini_sqr->subsquare(i);
5667
5668 if(Map.Scr(i)->valid&mVALID)
5669 {
5670 // Drawing is handled by mmap_draw.
5671 }
5672 else
5673 {
5674 if (InvalidBG == 2)
5675 {
5676 draw_checkerboard(screen, sqr.x, sqr.y, sqr.w);
5677 }
5678 else if (InvalidBG == 1)
5679 {
5680 draw_static_pos(sqr);
5681 }
5682 else
5683 {
5684 int32_t offs = 2*(sqr.w/9);
5685 draw_x(screen, sqr.x+offs, sqr.y+offs, sqr.x+sqr.w-1-offs, sqr.y+sqr.h-1-offs, vc(15));
5686 }
5687 }
5688 }
5689
5690 int32_t s=Map.getCurrScr();
5691
5692 BITMAP* txtbmp = create_bitmap_ex(8,256,64);
5693 clear_bitmap(txtbmp);
5694 int txtscale = zoomed_minimap ? (is_compact ? 2 : 3) : 1;
5695 font = get_zc_font(font_lfont_l);
5696
5697 int32_t space = text_length(font, "255")+2, spc_s = text_length(font, "S")+2, spc_m = text_length(font, "M")+2;
5698 textprintf_disabled(txtbmp,font,0,0,jwin_pal[jcLIGHT],jwin_pal[jcMEDDARK],"M");
5699 static int map_shortcut_tooltip_id = ttip_register_id();
5700 ttip_install(map_shortcut_tooltip_id, "Prev map: ,\nNext map: .", txt_x, txt_y, 30, 20, txt_x, txt_y - 60);
5701
5702 textprintf_ex(txtbmp,font,spc_m,0,jwin_pal[jcBOXFG],jwin_pal[jcBOX],"%-3d",Map.getCurrMap()+1);
5703
5704 textprintf_disabled(txtbmp,font,spc_m+space,0,jwin_pal[jcLIGHT],jwin_pal[jcMEDDARK],"S");
5705 textprintf_ex(txtbmp,font,spc_m+space+spc_s,0,jwin_pal[jcBOXFG],jwin_pal[jcBOX],"0x%02X (%d)",s, s);
5706 masked_stretch_blit(txtbmp, screen, 0, 0, 256, 64, txt_x, txt_y, 256*txtscale, 64*txtscale);
5707 destroy_bitmap(txtbmp);
5708 }
5709 }
5710 break;
5711 case rMAP:
5712 {
5713 refresh_visible_screens();
5714 mapscreen_single_scale = (double)mapscreen_screenunit_scale / Map.getViewSize();
5715
5716 int num_combos_width = 16 * Map.getViewSize();
5717 int num_combos_height = 11 * Map.getViewSize();
5718
5719 if(CurrentLayer > 0 && !mapscreen_valid_layers[CurrentLayer-1])
5720 CurrentLayer = 0;
5721
5722 if (HighQualityScreenRendering)
5723 {
5724 int startxint = mapscreen_x+(showedges?int(16*mapscreen_single_scale):0);
5725 int startyint = mapscreen_y+(showedges?int(16*mapscreen_single_scale):0);
5726 int w = 256*mapscreen_screenunit_scale*Map.getViewSize();
5727 int h = 176*mapscreen_screenunit_scale*Map.getViewSize();
5728
5729 MapViewRTI* rti_map_view = mapview_get_rti();
5730 rti_map_view->flags = Flags;
5731 rti_map_view->set_transform({.x = startxint, .y = startyint, .xscale = (float)mapscreen_single_scale, .yscale = (float)mapscreen_single_scale});
5732 rti_map_view->set_size(w, h);
5733 rti_map_view->dirty = true;
5734 rti_map_view->freeze = false;
5735 // TODO: could be improved. This currently makes the transform dirty every frame.
5736 get_root_rti()->add_child_before(rti_map_view, get_screen_rti());
5737 }
5738
5739 // Since the screen renders over the map view when HQR is enabled, the screen rti needs to be transparent.
5740 // But not if HQR is off, that would cause bugs when drawing color 0.
5741 get_screen_rti()->transparency_index = HighQualityScreenRendering ? 0 : -1;
5742
5743 for (auto& vis_screen : visible_screens)
5744 {
5745 draw_screenunit_map_screen(vis_screen);
5746 }
5747
5748 if (showxypos_icon)
5749 {
5750 int x0 = showxypos_x + (showedges?16:0);
5751 int y0 = showxypos_y + (showedges?16:0);
5752 int x1 = x0 + showxypos_w - 1;
5753 int y1 = y0 + showxypos_h - 1;
5754 x0 *= mapscreen_single_scale;
5755 y0 *= mapscreen_single_scale;
5756 x1 *= mapscreen_single_scale;
5757 y1 *= mapscreen_single_scale;
5758 x0 += mapscreen_x;
5759 y0 += mapscreen_y;
5760 x1 += mapscreen_x;
5761 y1 += mapscreen_y;
5762
5763 if (showxypos_color == vc(15))
5764 safe_rect(screen, x0, y0, x1, y1, showxypos_color);
5765 else
5766 rectfill(screen, x0, y0, x1, y1, showxypos_color);
5767 }
5768
5769 if(showxypos_cursor_icon)
5770 {
5771 int x0 = showxypos_cursor_x + (showedges?16:0);
5772 int y0 = showxypos_cursor_y + (showedges?16:0);
5773 int x1 = x0 + showxypos_w - 1;
5774 int y1 = y0 + showxypos_h - 1;
5775 x0 *= mapscreen_single_scale;
5776 y0 *= mapscreen_single_scale;
5777 x1 *= mapscreen_single_scale;
5778 y1 *= mapscreen_single_scale;
5779 x0 += mapscreen_x;
5780 y0 += mapscreen_y;
5781 x1 += mapscreen_x;
5782 y1 += mapscreen_y;
5783 safe_rect(screen, x0, y0, x1, y1, showxypos_cursor_color);
5784 }
5785
5786 // Draw dithering over the edge/preview combos.
5787 if(showedges)
5788 {
5789 int tile_size = 16 * mapscreen_single_scale;
5790 int tiles_across = (16 * Map.getViewSize()) + 2;
5791 int bottom_row_y = (Map.getViewSize()*11 + 1) * tile_size;
5792 int right_col_x = (Map.getViewSize()*16 + 1) * tile_size;
5793
5794 //top preview
5795 for(int32_t j=0; j<tile_size; j++)
5796 {
5797 for(int32_t i=0; i<tiles_across * tile_size; i++)
5798 {
5799 if(((i^j)&1)==0)
5800 {
5801 putpixel(screen,mapscreen_x+i,mapscreen_y+j,vc(0));
5802 }
5803 }
5804 }
5805
5806 //bottom preview
5807 for(int32_t j = bottom_row_y; j < bottom_row_y + tile_size; j++)
5808 {
5809 for(int32_t i=0; i<tiles_across * tile_size; i++)
5810 {
5811 if(((i^j)&1)==0)
5812 {
5813 putpixel(screen,mapscreen_x+i,mapscreen_y+j,vc(0));
5814 }
5815 }
5816 }
5817
5818 //left preview
5819 for(int32_t j=tile_size; j<int32_t(192*mapscreen_screenunit_scale); j++)
5820 {
5821 for(int32_t i=0; i<16*mapscreen_single_scale; i++)
5822 {
5823 if(((i^j)&1)==0)
5824 {
5825 putpixel(screen,mapscreen_x+i,mapscreen_y+j,vc(0));
5826 }
5827 }
5828 }
5829
5830 //right preview
5831 for(int32_t j=tile_size; j<int32_t(192*mapscreen_screenunit_scale); j++)
5832 {
5833 for(int32_t i = right_col_x; i < right_col_x + tile_size; i++)
5834 {
5835 if(((i^j)&1)==0)
5836 {
5837 putpixel(screen,mapscreen_x+i,mapscreen_y+j,vc(0));
5838 }
5839 }
5840 }
5841 }
5842
5843 if(!(Flags&cDEBUG) && pixeldb==2)
5844 {
5845 for(int32_t j=int32_t(168*mapscreen_single_scale); j<int32_t(176*mapscreen_single_scale); j++)
5846 {
5847 for(int32_t i=0; i<int32_t(256*mapscreen_single_scale); i++)
5848 {
5849
5850 if(((i^j)&1)==0)
5851 {
5852 putpixel(screen,int32_t(mapscreen_x+(showedges?(16*mapscreen_single_scale):0)+i),
5853 int32_t(mapscreen_y+(showedges?(16*mapscreen_single_scale):0)+j),vc(blackout_color));
5854 }
5855 }
5856 }
5857 }
5858
5859 // TODO: This should move to `zmap::draw` (and delete the current code there doing a similar thing).
5860 if (Map.isDark(Map.getCurrScr()) && Map.getViewSize() == 1)
5861 {
5862 if((Flags&cNEWDARK) && get_qr(qr_NEW_DARKROOM))
5863 {
5864 BITMAP* tmpDark = create_bitmap_ex(8,16*16,16*11);
5865 BITMAP* tmpDarkTrans = create_bitmap_ex(8,16*16,16*11);
5866 BITMAP* tmpbuf = create_bitmap_ex(8,
5867 mapscreen_single_scale*(256+(showedges?32:0)),
5868 mapscreen_single_scale*(176+(showedges?32:0)));
5869 BITMAP* tmpbuf2 = create_bitmap_ex(8,
5870 mapscreen_single_scale*(256+(showedges?32:0)),
5871 mapscreen_single_scale*(176+(showedges?32:0)));
5872 int32_t darkCol = zinit.darkcol;
5873 switch(darkCol) //special cases
5874 {
5875 case BLACK:
5876 darkCol = vc(0);
5877 break;
5878 case WHITE:
5879 darkCol = vc(15);
5880 break;
5881 }
5882 clear_to_color(tmpDark, darkCol);
5883 clear_to_color(tmpDarkTrans, darkCol);
5884 clear_bitmap(tmpbuf);
5885 clear_bitmap(tmpbuf2);
5886 //Handle torch combos
5887 color_map = trans_table2;
5888 Map.draw_darkness(tmpDark, tmpDarkTrans);
5889 //
5890 mapscr* tmp = Map.CurrScr();
5891 if(tmp->flags9 & fDARK_DITHER)
5892 {
5893 ditherblit(tmpDark, tmpDark, 0, zinit.dither_type, zinit.dither_arg);
5894 ditherblit(tmpDarkTrans, tmpDarkTrans, 0, zinit.dither_type, zinit.dither_arg);
5895 }
5896
5897 if(mapscreen_single_scale == 1)
5898 {
5899 blit(tmpDark, tmpbuf, 0, 0, (showedges?16:0), (showedges?16:0), 16*16, 16*11);
5900 blit(tmpDarkTrans, tmpbuf2, 0, 0, (showedges?16:0), (showedges?16:0), 16*16, 16*11);
5901 }
5902 else
5903 {
5904 stretch_blit(tmpDark, tmpbuf, 0, 0, 16*16, 16*11,
5905 (showedges?16:0)*mapscreen_single_scale, (showedges?16:0)*mapscreen_single_scale,
5906 (16*16)*mapscreen_single_scale, (16*11)*mapscreen_single_scale);
5907 stretch_blit(tmpDarkTrans, tmpbuf2, 0, 0, 16*16, 16*11,
5908 (showedges?16:0)*mapscreen_single_scale, (showedges?16:0)*mapscreen_single_scale,
5909 (16*16)*mapscreen_single_scale, (16*11)*mapscreen_single_scale);
5910 }
5911
5912 if(tmp->flags9 & fDARK_TRANS)
5913 {
5914 draw_trans_sprite(screen, tmpbuf, mapscreen_x, mapscreen_y);
5915 }
5916 else
5917 {
5918 masked_blit(tmpbuf,screen,0,0,mapscreen_x,mapscreen_y,tmpbuf->w,tmpbuf->h);
5919 }
5920 draw_trans_sprite(screen, tmpbuf2, mapscreen_x, mapscreen_y);
5921 color_map = trans_table;
5922 //
5923 destroy_bitmap(tmpDark);
5924 destroy_bitmap(tmpDarkTrans);
5925 destroy_bitmap(tmpbuf);
5926 destroy_bitmap(tmpbuf2);
5927 }
5928 else if(!(Flags&cNODARK))
5929 {
5930 for(int32_t j=0; j<80*mapscreen_single_scale; j++)
5931 {
5932 for(int32_t i=0; i<(80*mapscreen_single_scale)-j; i++)
5933 {
5934 if(((i^j)&1)==0)
5935 {
5936 putpixel(screen,int32_t(mapscreen_x+(showedges?(16*mapscreen_single_scale):0))+i,
5937 int32_t(mapscreen_y+(showedges?(16*mapscreen_single_scale):0)+j),vc(blackout_color));
5938 }
5939 }
5940 }
5941 }
5942 }
5943
5944 double startx=mapscreen_x+(showedges?(16*mapscreen_single_scale):0);
5945 double starty=mapscreen_y+(showedges?(16*mapscreen_single_scale):0);
5946 bool inrect = isinRect(gui_mouse_x(),gui_mouse_y(),startx,starty,(startx+(256*mapscreen_screenunit_scale)-1),(starty+(176*mapscreen_screenunit_scale)-1));
5947
5948 if(!(flags&rNOCURSOR) && ((ComboBrush && !ComboBrushPause)||draw_mode==dm_alias) && inrect)
5949 {
5950 int mgridscale=16*mapscreen_single_scale;
5951 if(allowHideMouse)
5952 {
5953 if(arrowcursor)
5954 {
5955 arrowcursor = false;
5956 MouseSprite::set(ZQM_BLANK);
5957 }
5958 }
5959 else if(!arrowcursor)
5960 {
5961 arrowcursor = true;
5962 MouseSprite::set(ZQM_NORMAL);
5963 }
5964 ComboPosition pos = get_mapscreen_mouse_combo_pos();
5965 int32_t mx = pos.x * 16 * mapscreen_single_scale;
5966 int32_t my = pos.y * 16 * mapscreen_single_scale;
5967
5968 clear_bitmap(brushscreen);
5969 int32_t tempbw=BrushWidth;
5970 int32_t tempbh=BrushHeight;
5971
5972 if(draw_mode==dm_alias)
5973 {
5974 BrushWidth = combo_aliases[combo_apos].width+1;
5975 BrushHeight = combo_aliases[combo_apos].height+1;
5976 }
5977 else if(draw_mode == dm_cpool)
5978 {
5979 BrushWidth = BrushHeight = 1;
5980 combo_pool const& pool = combo_pools[combo_pool_pos];
5981 if(pool.valid())
5982 {
5983 int32_t cid = Combo;
5984 int8_t cset = CSet;
5985 pool.get_w_wrap(cid,cset,cpoolbrush_index/16); //divide to reduce speed
5986 put_combo(brushbmp,0,0,cid,cset,Flags&(cFLAGS|cWALK),0);
5987 }
5988 else clear_bitmap(brushbmp);
5989 }
5990 else if (draw_mode == dm_auto)
5991 {
5992 BrushWidth = BrushHeight = 1;
5993 }
5994
5995 stretch_blit(brushbmp, brushscreen, 0, 0, BrushWidth*16, BrushHeight*16, 0, 0, BrushWidth*mgridscale, BrushHeight*mgridscale);
5996 int float_offx = 0;
5997 int float_offy = 0;
5998
5999 if(FloatBrush)
6000 {
6001 float_offx = -SHADOW_DEPTH*mapscreen_single_scale;
6002 float_offy = -SHADOW_DEPTH*mapscreen_single_scale;
6003
6004 //shadow
6005 for(int x = 0; x < SHADOW_DEPTH*mapscreen_single_scale; ++x)
6006 for(int y = 0; y < (BrushHeight*mgridscale) + (SHADOW_DEPTH*mapscreen_single_scale); ++y)
6007 {
6008 if((((x^y)&1)==1) && y < 12*mgridscale)
6009 putpixel(brushscreen,x+(BrushWidth*mgridscale),y,vc(0));
6010 }
6011
6012 for(int x = 0; x < BrushWidth*mgridscale; ++x)
6013 for(int y = 0; y < SHADOW_DEPTH*mapscreen_single_scale; ++y)
6014 {
6015 if((((x^y)&1)==1) && x<16*mgridscale)
6016 putpixel(brushscreen,x,y+(BrushHeight*mgridscale),vc(0));
6017 }
6018 }
6019
6020 if(draw_mode==dm_alias)
6021 {
6022 combo_alias *combo = &combo_aliases[combo_apos];
6023
6024 if(BrushWidth > 1 && (alias_origin & 1)) //right-align
6025 float_offx -= (BrushWidth - 1) * mgridscale;
6026
6027 if(BrushHeight > 1 && (alias_origin & 2)) //bottom-align
6028 float_offy -= (BrushHeight - 1) * mgridscale;
6029 }
6030
6031 int bx = mapscreen_x + mx + float_offx + (showedges?(16*mapscreen_single_scale):0);
6032 int by = mapscreen_y + my + float_offy + (showedges?(16*mapscreen_single_scale):0);
6033 masked_blit(brushscreen, screen, 0, 0, bx, by, 16*mgridscale, 11*mgridscale);
6034 BrushWidth=tempbw;
6035 BrushHeight=tempbh;
6036 }
6037 else
6038 {
6039 if(!arrowcursor)
6040 {
6041 MouseSprite::set(ZQM_NORMAL);
6042 arrowcursor = true;
6043 }
6044 }
6045
6046 int startxint = mapscreen_x+(showedges?int(16*mapscreen_single_scale):0);
6047 int startyint = mapscreen_y+(showedges?int(16*mapscreen_single_scale):0);
6048 int endxint = startx + 256*mapscreen_screenunit_scale - 1;
6049 int endyint = starty + 176*mapscreen_screenunit_scale - 1;
6050 set_clip_rect(screen,startxint,startyint,endxint,endyint);
6051
6052 if(ShowGrid)
6053 {
6054 int w = num_combos_width;
6055 int h = num_combos_height;
6056 double tile_size = 16.0 / Map.getViewSize() * mapscreen_screenunit_scale;
6057
6058 if(showedges)
6059 {
6060 w += 2;
6061 h += 2;
6062 }
6063
6064 for (int x = 1; x < w; x++)
6065 {
6066 vline(screen, mapscreen_x + x*tile_size, mapscreen_y, mapscreen_y + (h*tile_size)-1, vc(GridColor));
6067 }
6068
6069 for (int y = 1; y < h; y++)
6070 {
6071 hline(screen, mapscreen_x, mapscreen_y + y*tile_size, mapscreen_x + (w*tile_size)-1, vc(GridColor));
6072 }
6073 }
6074
6075 if(ShowScreenGrid)
6076 {
6077 int w = num_combos_width;
6078 int h = num_combos_height;
6079 double tile_size = 16.0 / Map.getViewSize() * mapscreen_screenunit_scale;
6080 int startx = mapscreen_x + (showedges ? (16 * mapscreen_single_scale) : 0);
6081 int starty = mapscreen_y + (showedges ? (16 * mapscreen_single_scale) : 0);
6082
6083 if(showedges)
6084 {
6085 w += 1;
6086 h += 1;
6087 }
6088
6089 int color = (GridColor+8)%16;
6090
6091 for (int x = 16; x < w; x+=16)
6092 {
6093 vline(screen, startx + x*tile_size, mapscreen_y, starty + (h*tile_size)-1, vc(color));
6094 }
6095
6096 for (int y = 11; y < h; y+=11)
6097 {
6098 hline(screen, startx, starty + y*tile_size, startx + (w*tile_size)-1, vc(color));
6099 }
6100 }
6101
6102 // Draw a rect around regions.
6103 if (ShowRegionGrid && Map.getViewSize() > 1)
6104 {
6105 for (const auto& region_description : Map.get_region_descriptions())
6106 {
6107 int sx = region_description.screen % 16;
6108 int sy = region_description.screen / 16;
6109 int sw = region_description.w;
6110 int sh = region_description.h;
6111
6112 int mw = 256 * mapscreen_single_scale;
6113 int mh = 176 * mapscreen_single_scale;
6114 int mx = sx - (Map.getViewScr() % 16);
6115 int my = sy - (Map.getViewScr() / 16);
6116 int x0 = mapscreen_x + (showedges ? (16 * mapscreen_single_scale) : 0) + mx * mw;
6117 int y0 = mapscreen_y + (showedges ? (16 * mapscreen_single_scale) : 0) + my * mh;
6118 rect(screen, x0+2, y0+2, x0 + mw*sw - 2, y0 + mh*sh - 2, vc(1));
6119 rect(screen, x0+1, y0+1, x0 + mw*sw - 1, y0 + mh*sh - 1, vc(15));
6120 rect(screen, x0, y0, x0 + mw*sw, y0 + mh*sh, vc(1));
6121 }
6122 }
6123
6124 // Draw a black-yellow-black rect around the currently selected screen.
6125 if (ShowCurScreenOutline && Map.getViewSize() > 1)
6126 {
6127 int mw = 256 * mapscreen_single_scale;
6128 int mh = 176 * mapscreen_single_scale;
6129 int mx = (Map.getCurrScr() % 16) - (Map.getViewScr() % 16);
6130 int my = (Map.getCurrScr() / 16) - (Map.getViewScr() / 16);
6131 int x0 = mapscreen_x + (showedges ? (16 * mapscreen_single_scale) : 0) + mx * mw;
6132 int y0 = mapscreen_y + (showedges ? (16 * mapscreen_single_scale) : 0) + my * mh;
6133 dotted_rect(screen, x0+2, y0+2, x0 + mw - 2, y0 + mh - 2, vc(1), vc(0));
6134 rect(screen, x0+1, y0+1, x0 + mw - 1, y0 + mh - 1, vc(14));
6135 dotted_rect(screen, x0, y0, x0 + mw, y0 + mh, vc(1), vc(0));
6136 }
6137
6138 clear_clip_rect(screen);
6139
6140 // Map tabs
6141 font = get_custom_font(CFONT_GUI);
6142
6143 map_page[current_mappage].map=Map.getCurrMap();
6144 map_page[current_mappage].screen=Map.getCurrScr();
6145
6146 for(int32_t btn=0; btn<mappage_count; ++btn)
6147 {
6148 char tbuf[15];
6149 sprintf(tbuf, "%d:%02X", map_page[btn].map+1, map_page[btn].screen);
6150 draw_layer_button(screen,map_page_bar[btn].x, map_page_bar[btn].y, map_page_bar[btn].w, map_page_bar[btn].h,tbuf,(btn==current_mappage?D_SELECTED:0));
6151 }
6152 }
6153 break;
6154 case rCOMBOS:
6155 {
6156 auto real_h = combolist_window.h;
6157 jwin_draw_frame(screen,combolist_window.x,combolist_window.y,combolist_window.w,real_h, FR_WIN);
6158 rectfill(screen,combolist_window.x+2,combolist_window.y+2,combolist_window.x+combolist_window.w-3,combolist_window.y+real_h-3,jwin_pal[jcBOX]);
6159
6160 //Scrollers
6161 for(int32_t c = 0; c < num_combo_cols; ++c)
6162 {
6163 auto& pos = combolistscrollers[c];
6164
6165 { //Scroll up
6166 auto& p = pos.subsquare(0);
6167 jwin_draw_frame(screen,p.x,p.y,p.w,p.h,FR_ETCHED);
6168
6169 for(int32_t i=0; i<3; i++)
6170 {
6171 hline(screen, p.x+5-i, p.y+4+i, p.x+5+i, jwin_pal[jcBOXFG]);
6172 }
6173 }
6174
6175 { //Scroll down
6176 auto& p = pos.subsquare(1);
6177 jwin_draw_frame(screen,p.x,p.y,p.w,p.h,FR_ETCHED);
6178
6179 for(int32_t i=0; i<3; i++)
6180 {
6181 hline(screen,p.x+5-i,p.y+6-i, p.x+5+i, jwin_pal[jcBOXFG]);
6182 }
6183 }
6184 }
6185
6186 if(draw_mode==dm_alias)
6187 {
6188 if(LinkedScroll)
6189 {
6190 int tmp = current_comboalist;
6191 for(int q = tmp-1; q >= 0; --q)
6192 {
6193 combo_alistpos[q] = combo_alistpos[q+1]-(comboaliaslist[q].w*comboaliaslist[q].h);
6194 if(combo_alistpos[q] < 0)
6195 {
6196 tmp = 0;
6197 combo_alistpos[0] = 0;
6198 break;
6199 }
6200 }
6201 for(int q = tmp+1; q < num_combo_cols; ++q)
6202 combo_alistpos[q] = combo_alistpos[q-1]+(comboaliaslist[q-1].w*comboaliaslist[q-1].h);
6203 for(int q = 0; q < num_combo_cols; ++q)
6204 if(combo_apos >= combo_alistpos[q] && combo_apos < combo_alistpos[q] + (comboaliaslist[q].w*comboaliaslist[q].h))
6205 {
6206 current_comboalist = q;
6207 break;
6208 }
6209 }
6210 for(int32_t c = 0; c < num_combo_cols; ++c)
6211 {
6212 auto& pos = comboaliaslist[c];
6213 rectfill(screen,pos.x,pos.y,pos.x+(pos.w*pos.xscale)-1,pos.y+(pos.h*pos.yscale)-1,0);
6214 jwin_draw_frame(screen,pos.x-2,pos.y-2,(pos.w*pos.xscale)+4,(pos.h*pos.yscale)+4,FR_DEEP);
6215 }
6216
6217 auto& prev = comboalias_preview;
6218 jwin_draw_frame(screen, prev.x-2, prev.y-2, prev.w+4, prev.h+4,FR_DEEP);
6219
6220 BITMAP *prv = create_bitmap_ex(8,64,64);
6221 clear_bitmap(prv);
6222 int32_t scalefactor = 1;
6223
6224 for(int32_t j=0; j<num_combo_cols; ++j)
6225 {
6226 auto per_page = (comboaliaslist[j].w * comboaliaslist[j].h);
6227 if(combo_alistpos[j] + per_page >= MAXCOMBOALIASES)
6228 combo_alistpos[j] = MAXCOMBOALIASES-per_page;
6229 auto& col = comboaliaslist[j];
6230 for(int32_t i=0; i<(comboaliaslist[j].w*comboaliaslist[j].h); i++)
6231 {
6232 draw_combo_alias_thumbnail(screen, &combo_aliases[combo_alistpos[j]+i],
6233 (i%col.w)*col.xscale+col.x, (i/col.w)*col.yscale+col.y, col.xscale/16);
6234 }
6235
6236 if((combo_aliases[combo_apos].width>7)||(combo_aliases[combo_apos].height>7))
6237 {
6238 scalefactor=4;
6239 }
6240 else if((combo_aliases[combo_apos].width>3)||(combo_aliases[combo_apos].height>3))
6241 {
6242 scalefactor=2;
6243 }
6244
6245
6246 if(j==current_comboalist)
6247 {
6248 stretch_blit(brushbmp, prv, 0,0,scalefactor*64,zc_min(scalefactor*64,176),0,0,64,scalefactor==4?44:64);
6249 blit(prv,screen,0,0,comboalias_preview.x,comboalias_preview.y,comboalias_preview.w,comboalias_preview.h);
6250
6251 int32_t rect_pos=combo_apos-combo_alistpos[current_comboalist];
6252
6253 if((rect_pos>=0)&&(rect_pos<(combo_alistpos[current_comboalist]+(col.w*col.h))))
6254 {
6255 int selw = col.xscale;
6256 int selh = col.yscale;
6257 int x1 = (rect_pos&(col.w-1))*col.xscale+col.x;
6258 int y1 = (rect_pos/col.w)*col.yscale+col.y;
6259 safe_rect(screen,x1,y1,x1+selw-1,y1+selh-1,vc(CmbCursorCol),2);
6260 }
6261 }
6262 }
6263
6264 destroy_bitmap(prv);
6265 }
6266 else if(draw_mode==dm_cpool)
6267 {
6268 if(LinkedScroll)
6269 {
6270 int tmp = current_cpoollist;
6271 for(int q = tmp-1; q >= 0; --q)
6272 {
6273 combo_pool_listpos[q] = combo_pool_listpos[q+1]-(comboaliaslist[q].w*comboaliaslist[q].h);
6274 if(combo_pool_listpos[q] < 0)
6275 {
6276 tmp = 0;
6277 combo_pool_listpos[0] = 0;
6278 break;
6279 }
6280 }
6281 for(int q = tmp+1; q < num_combo_cols; ++q)
6282 combo_pool_listpos[q] = combo_pool_listpos[q-1]+(comboaliaslist[q-1].w*comboaliaslist[q-1].h);
6283 for(int q = 0; q < num_combo_cols; ++q)
6284 if(combo_pool_pos >= combo_pool_listpos[q] && combo_pool_pos < combo_pool_listpos[q] + (comboaliaslist[q].w*comboaliaslist[q].h))
6285 {
6286 current_cpoollist = q;
6287 break;
6288 }
6289 }
6290 for(int32_t c = 0; c < num_combo_cols; ++c)
6291 {
6292 auto& pos = comboaliaslist[c];
6293 rectfill(screen,pos.x,pos.y,pos.x+(pos.w*pos.xscale)-1,pos.y+(pos.h*pos.yscale)-1,0);
6294 jwin_draw_frame(screen,pos.x-2,pos.y-2,(pos.w*comboaliaslist[c].xscale)+4,(pos.h*comboaliaslist[c].yscale)+4,FR_DEEP);
6295 }
6296
6297 for (int32_t j = 0; j < num_combo_cols; ++j) //the actual panes
6298 {
6299 auto per_page = (comboaliaslist[j].w * comboaliaslist[j].h);
6300 if(combo_pool_listpos[j] + per_page >= MAXCOMBOPOOLS)
6301 combo_pool_listpos[j] = MAXCOMBOPOOLS-per_page;
6302 for(int32_t i=0; i<(comboaliaslist[j].w*comboaliaslist[j].h); i++)
6303 {
6304 int32_t cid=-1; int8_t cs=CSet;
6305 combo_pool const& cp = combo_pools[combo_pool_listpos[j]+i];
6306
6307 auto& list = comboaliaslist[j];
6308 if(cp.get_w(cid,cs,0) && !combobuf[cid].tile)
6309 {
6310 cid = -1; //no tile to draw
6311 }
6312 auto cx = (i%list.w)*list.xscale+list.x;
6313 auto cy = (i/list.w)*list.yscale+list.y;
6314 put_combo(screen,cx,cy,cid,cs,Flags&(cFLAGS|cWALK),0,list.xscale/16);
6315 }
6316 }
6317 int32_t rect_pos=combo_pool_pos-combo_pool_listpos[current_cpoollist];
6318
6319 if((rect_pos>=0)&&(rect_pos<(combo_pool_listpos[current_cpoollist]+(comboaliaslist[current_cpoollist].w*comboaliaslist[current_cpoollist].h))))
6320 {
6321 int selw = comboaliaslist[current_cpoollist].xscale;
6322 int selh = comboaliaslist[current_cpoollist].yscale;
6323 int x1 = (rect_pos&(comboaliaslist[current_cpoollist].w-1))*comboaliaslist[current_cpoollist].xscale+comboaliaslist[current_cpoollist].x;
6324 int y1 = (rect_pos/comboaliaslist[current_cpoollist].w)*comboaliaslist[current_cpoollist].yscale+comboaliaslist[current_cpoollist].y;
6325 safe_rect(screen,x1,y1,x1+selw-1,y1+selh-1,vc(CmbCursorCol),2);
6326 }
6327
6328 //Handle Preview
6329 combo_pool const& cpool = combo_pools[combo_pool_pos];
6330
6331 int32_t cid; int8_t cs;
6332 size_t total = weighted_cpool ? cpool.getTotalWeight() : cpool.combos.size();
6333 size_t ind = 0;
6334 size_t indw = combopool_preview.w/16;
6335 size_t indh = combopool_preview.h/16;
6336 size_t rows = total ? vbound(total/indw,1,indh) : 0;
6337 if (is_compact)
6338 rows = vbound(rows, 1, 3);
6339 else
6340 rows = vbound(rows, 1, 4);
6341 size_t real_height = rows*16;
6342
6343 cpool_prev_visible = rows > 0;
6344 if(rows)
6345 {
6346 jwin_draw_frame(screen,combopool_preview.x-2,combopool_preview.y-2,
6347 combopool_preview.w+4,real_height+4,FR_DEEP);
6348 rectfill(screen,combopool_preview.x,combopool_preview.y,
6349 combopool_preview.x+combopool_preview.w-1,
6350 combopool_preview.y+real_height-1,vc(0));
6351 draw_text_button(screen,combopool_prevbtn.x,combopool_prevbtn.y,
6352 combopool_prevbtn.w,combopool_prevbtn.h,
6353 weighted_cpool ? "Weighted" : "Unweighted",vc(1),vc(14),0,true);
6354 if(!is_compact)
6355 textprintf_ex(screen,font,combopool_prevbtn.x+combopool_prevbtn.w+5,
6356 combopool_prevbtn.y,jwin_pal[jcBOXFG],-1,"Preview");
6357 for(auto y = 0; y < real_height; y += 16)
6358 {
6359 for(auto x = 0; x < combopool_preview.w; x += 16, ++ind)
6360 {
6361 auto nx = combopool_preview.x+x, ny = combopool_preview.y+y;
6362 if(ind < total)
6363 {
6364 cs = CSet;
6365 if(weighted_cpool
6366 ? cpool.get_w(cid,cs,ind)
6367 : cpool.get_ind(cid,cs,ind))
6368 {
6369 put_combo(screen,nx,ny,cid,cs,Flags&(cFLAGS|cWALK),0);
6370 continue;
6371 }
6372 }
6373 //No combo to display
6374 xout(screen, nx, ny, nx+15, ny+15, vc(15));
6375 }
6376 }
6377 }
6378 }
6379 else if (draw_mode == dm_auto)
6380 {
6381 if (LinkedScroll)
6382 {
6383 int tmp = current_cautolist;
6384 for (int q = tmp - 1; q >= 0; --q)
6385 {
6386 combo_auto_listpos[q] = combo_auto_listpos[q + 1] - (comboaliaslist[q].w * comboaliaslist[q].h);
6387 if (combo_auto_listpos[q] < 0)
6388 {
6389 tmp = 0;
6390 combo_auto_listpos[0] = 0;
6391 break;
6392 }
6393 }
6394 for (int q = tmp + 1; q < num_combo_cols; ++q)
6395 combo_auto_listpos[q] = combo_auto_listpos[q - 1] + (comboaliaslist[q - 1].w * comboaliaslist[q - 1].h);
6396 for (int q = 0; q < num_combo_cols; ++q)
6397 if (combo_auto_pos >= combo_auto_listpos[q] && combo_auto_pos < combo_auto_listpos[q] + (comboaliaslist[q].w * comboaliaslist[q].h))
6398 {
6399 current_cautolist = q;
6400 break;
6401 }
6402 }
6403 for (int32_t c = 0; c < num_combo_cols; ++c)
6404 {
6405 auto& pos = comboaliaslist[c];
6406 rectfill(screen, pos.x, pos.y, pos.x + (pos.w * pos.xscale) - 1, pos.y + (pos.h * pos.yscale) - 1, 0);
6407 jwin_draw_frame(screen, pos.x - 2, pos.y - 2, (pos.w * comboaliaslist[c].xscale) + 4, (pos.h * comboaliaslist[c].yscale) + 4, FR_DEEP);
6408 }
6409
6410 for (int32_t j = 0; j < num_combo_cols; ++j) //the actual panes
6411 {
6412 auto per_page = (comboaliaslist[j].w * comboaliaslist[j].h);
6413 if(combo_auto_listpos[j] + per_page >= MAXAUTOCOMBOS)
6414 combo_auto_listpos[j] = MAXAUTOCOMBOS-per_page;
6415 for (int32_t i = 0; i < (comboaliaslist[j].w * comboaliaslist[j].h); i++)
6416 {
6417 int32_t cid = -1; int8_t cs = CSet;
6418 combo_auto const& ca = combo_autos[combo_auto_listpos[j] + i];
6419
6420 auto& list = comboaliaslist[j];
6421 cid = ca.getDisplay();
6422 if (cid == 0)
6423 cid = -1;
6424 auto cx = (i % list.w) * list.xscale + list.x;
6425 auto cy = (i / list.w) * list.yscale + list.y;
6426 put_combo(screen, cx, cy, cid, cs, Flags & (cFLAGS | cWALK), 0, list.xscale / 16);
6427 put_autocombo_engravings(screen, ca, combo_auto_listpos[j] + i == combo_auto_pos, cx, cy, list.xscale / 16);
6428 }
6429 }
6430 int32_t rect_pos = combo_auto_pos - combo_auto_listpos[current_cautolist];
6431
6432 if ((rect_pos >= 0) && (rect_pos < (combo_auto_listpos[current_cautolist] + (comboaliaslist[current_cautolist].w * comboaliaslist[current_cautolist].h))))
6433 {
6434 int selw = comboaliaslist[current_cautolist].xscale;
6435 int selh = comboaliaslist[current_cautolist].yscale;
6436 int x1 = (rect_pos & (comboaliaslist[current_cautolist].w - 1)) * comboaliaslist[current_cautolist].xscale + comboaliaslist[current_cautolist].x;
6437 int y1 = (rect_pos / comboaliaslist[current_cautolist].w) * comboaliaslist[current_cautolist].yscale + comboaliaslist[current_cautolist].y;
6438 safe_rect(screen, x1, y1, x1 + selw - 1, y1 + selh - 1, vc(CmbCursorCol), 2);
6439
6440 combo_auto const& ca = combo_autos[combo_auto_pos];
6441 put_autocombo_engravings(screen, ca, true, x1, y1, selw / 16);
6442 }
6443 }
6444 else
6445 {
6446 if(LinkedScroll)
6447 {
6448 int tmp = current_combolist;
6449 for(int q = tmp-1; q >= 0; --q)
6450 {
6451 First[q] = First[q+1]-(combolist[q].w*combolist[q].h);
6452 if(First[q] < 0)
6453 {
6454 tmp = 0;
6455 First[0] = 0;
6456 break;
6457 }
6458 }
6459 for(int q = tmp+1; q < num_combo_cols; ++q)
6460 First[q] = First[q-1]+(combolist[q-1].w*combolist[q-1].h);
6461 for(int q = 0; q < num_combo_cols; ++q)
6462 if(Combo >= First[q] && Combo < First[q] + (combolist[q].w*combolist[q].h))
6463 {
6464 current_combolist = q;
6465 break;
6466 }
6467 }
6468 for(int32_t c = 0; c < num_combo_cols; ++c)
6469 {
6470 auto& pos = combolist[c];
6471 rectfill(screen,pos.x,pos.y,pos.x+(pos.w*pos.xscale)-1,pos.y+(pos.h*pos.yscale)-1,0);
6472 jwin_draw_frame(screen,pos.x-2,pos.y-2,(pos.w*pos.xscale)+4,(pos.h*pos.yscale)+4,FR_DEEP);
6473 }
6474
6475 int32_t drawmap, drawscr;
6476 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
6477 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
6478
6479 for(int32_t j=0; j<num_combo_cols; ++j)
6480 {
6481 auto per_page = (combolist[j].w * combolist[j].h);
6482 if(First[j] + per_page >= MAXCOMBOS)
6483 First[j] = MAXCOMBOS-per_page;
6484 for(int32_t i=0; i<(combolist[j].w*combolist[j].h); i++)
6485 {
6486 put_combo(screen,(i%combolist[j].w)*combolist[j].xscale+combolist[j].x,
6487 (i/combolist[j].w)*combolist[j].yscale+combolist[j].y,
6488 i+First[j],CSet,Flags&(cFLAGS|cWALK),0,combolist[j].xscale/16);
6489 }
6490 }
6491
6492 int32_t rect_pos=Combo-First[current_combolist];
6493
6494 if((rect_pos>=0)&&(rect_pos<(combo_pool_listpos[current_combolist]+(combolist[current_combolist].w*combolist[current_combolist].h))))
6495 {
6496 int selw = (AutoBrush?BrushWidth:1)*combolist[current_combolist].xscale;
6497 int selh = (AutoBrush?BrushHeight:1)*combolist[current_combolist].yscale;
6498 int x1 = (rect_pos&(combolist[current_combolist].w-1))*combolist[current_combolist].xscale+combolist[current_combolist].x;
6499 int y1 = (rect_pos/combolist[current_combolist].w)*combolist[current_combolist].yscale+combolist[current_combolist].y;
6500 safe_rect(screen,x1,y1,x1+selw-1,y1+selh-1,vc(CmbCursorCol),2);
6501 }
6502 }
6503 }
6504 break;
6505 case rCOMBO:
6506 {
6507 int32_t drawmap, drawscr;
6508 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
6509 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
6510
6511 // Combo preview
6512 int32_t cid = Combo; int8_t cs = CSet;
6513 if(draw_mode == dm_alias)
6514 {
6515 cid = combo_aliases[combo_apos].combos[0];
6516 cs = wrap(combo_aliases[combo_apos].csets[0]+alias_cset_mod, 0, 13);
6517 }
6518 else if(draw_mode == dm_cpool)
6519 {
6520 combo_pool const& cpool = combo_pools[combo_pool_pos];
6521 cid = 0;
6522 cpool.get_w(cid,cs,0);
6523 }
6524 else if (draw_mode == dm_auto)
6525 {
6526 combo_auto const& cauto = combo_autos[combo_auto_pos];
6527 cid = cauto.getDisplay();
6528 }
6529 static BITMAP *combo_preview_bmp=create_bitmap_ex(8,32,32);
6530 static BITMAP *cycle_preview_bmp=create_bitmap_ex(8,32,32);
6531 // Combo
6532 put_combo(combo_preview_bmp,0,0,cid,cs,Flags&(cFLAGS|cWALK),0);
6533 jwin_draw_frame(screen,combo_preview.x-2,combo_preview.y-2,combo_preview.w+4,combo_preview.h+4, FR_DEEP);
6534 stretch_blit(combo_preview_bmp, screen, 0, 0, 16, 16, combo_preview.x, combo_preview.y, combo_preview.w, combo_preview.h);
6535
6536 comboprev_buf[0] = 0;
6537 comboprev_buf2[0] = 0;
6538 if(draw_mode == dm_cpool)
6539 {
6540 sprintf(comboprev_buf,"Pool: %d\nCSet: %d",combo_pool_pos,CSet);
6541 int x = combo_preview_text1.x+(combo_preview_text1.w*combo_preview_text1.xscale);
6542 textbox_out(screen,txfont,x,combo_preview_text1.y,jwin_pal[jcBOXFG],jwin_pal[jcBOX],comboprev_buf,2,&combo_preview_text1);
6543 }
6544 else if (draw_mode == dm_auto)
6545 {
6546 GUI::ListData ac_types = GUI::ZCListData::autocombotypes();
6547 std::string type_name = ac_types.findText(combo_autos[combo_auto_pos].getType());
6548 if (is_compact)
6549 sprintf(comboprev_buf, "AC: %d CS: %d\n%s", combo_auto_pos, CSet, type_name.c_str());
6550 else
6551 sprintf(comboprev_buf, "Auto: %d CSet: %d\n%s\nEntries: %d", combo_auto_pos, CSet, type_name.c_str(), int32_t(combo_autos[combo_auto_pos].combos.size()));
6552 int x = combo_preview_text1.x + (combo_preview_text1.w * combo_preview_text1.xscale);
6553 textbox_out(screen, txfont, x, combo_preview_text1.y, jwin_pal[jcBOXFG], jwin_pal[jcBOX], comboprev_buf, 2, &combo_preview_text1);
6554 }
6555 else if(draw_mode != dm_alias)
6556 {
6557 int x = combo_preview_text1.x+(combo_preview_text1.w*combo_preview_text1.xscale);
6558
6559 char shortbuf[512];
6560 char buf[256];
6561 strcpy(buf,combo_class_buf[combobuf[Combo].type].name);
6562 sprintf(comboprev_buf,"Combo: %d\nCSet: %d\n%s",Combo,CSet,buf);
6563 int ind = strlen(buf)-1;
6564 int x2 = x;
6565 if(x2 - text_length(txfont, buf) <= combolist_window.x)
6566 {
6567 auto dotlen = text_length(txfont, "..");
6568 x2 -= dotlen;
6569 while(x2 - text_length(txfont, buf) <= combolist_window.x)
6570 {
6571 if(ind < 0) break;
6572 buf[ind--] = '\0';
6573 }
6574 while(ind >= 0 && buf[ind] == ' ')
6575 buf[ind--] = 0; //trim spaces
6576 strcat(buf, "..");
6577 }
6578
6579 if(is_compact)
6580 {
6581 char b2[256];
6582 sprintf(b2, "Combo %d CS %d", Combo, CSet);
6583 if(x-text_length(txfont, b2) <= combolist_window.x)
6584 sprintf(b2, "Cmb %d CS %d", Combo, CSet);
6585 sprintf(shortbuf,"%s\n%s",b2,buf);
6586 }
6587 else sprintf(shortbuf,"Combo: %d\nCSet: %d\n%s",Combo,CSet,buf);
6588 textbox_out(screen,txfont,x,combo_preview_text1.y,jwin_pal[jcBOXFG],jwin_pal[jcBOX],shortbuf,2,&combo_preview_text1);
6589 }
6590
6591 // Cycle
6592 if(!is_compact)
6593 {
6594 int32_t NextCombo = combobuf[Combo].nextcombo;
6595 int32_t NextCSet = combobuf[Combo].nextcset;
6596 if(combobuf[Combo].animflags & AF_CYCLEUNDERCOMBO)
6597 {
6598 mapscr* scr = Map.CurrScr();
6599 NextCombo = scr->undercombo;
6600 NextCSet = scr->undercset;
6601 }
6602 if(combobuf[Combo].animflags & AF_CYCLENOCSET)
6603 NextCSet = CSet;
6604 bool normal_dm = draw_mode != dm_alias && draw_mode != dm_cpool && draw_mode != dm_auto;
6605 jwin_draw_frame(screen,combo_preview2.x-2,combo_preview2.y-2,combo_preview2.w+4,combo_preview2.h+4, FR_DEEP);
6606 if(NextCombo>0 && normal_dm)
6607 {
6608 put_combo(cycle_preview_bmp,0,0,NextCombo,NextCSet,Flags&(cFLAGS|cWALK),0);
6609
6610 if(Flags&cWALK) put_walkflags(cycle_preview_bmp,0,0,NextCombo,0);
6611
6612 if(Flags&cFLAGS) put_flags(cycle_preview_bmp,0,0,NextCombo,0,cFLAGS,0);
6613
6614 stretch_blit(cycle_preview_bmp, screen, 0, 0, 16, 16, combo_preview2.x, combo_preview2.y, combo_preview2.w, combo_preview2.h);
6615 }
6616 else
6617 {
6618 if (InvalidBG == 2)
6619 {
6620 draw_checkerboard(screen, combo_preview2.x, combo_preview2.y, 32);
6621 }
6622 else if(InvalidBG == 1)
6623 {
6624 draw_static_pos(combo_preview2);
6625 }
6626 else
6627 {
6628 rectfill(screen, combo_preview2.x,combo_preview2.y, combo_preview2.x+32,combo_preview2.y+combo_preview2.h,vc(0));
6629 safe_rect(screen, combo_preview2.x,combo_preview2.y, combo_preview2.x+32,combo_preview2.y+combo_preview2.h,vc(15));
6630 line(screen, combo_preview2.x,combo_preview2.y, combo_preview2.x+32,combo_preview2.y+combo_preview2.h,vc(15));
6631 line(screen, combo_preview2.x,combo_preview2.y+combo_preview2.h, combo_preview2.x+32,combo_preview2.y,vc(15));
6632 }
6633 }
6634
6635 if(normal_dm)
6636 {
6637 char shortbuf[512];
6638 char buf[256];
6639 strcpy(buf,combo_class_buf[combobuf[NextCombo].type].name);
6640 sprintf(comboprev_buf2, "Cycle: %d\nCSet: %d\n%s", NextCombo, NextCSet, buf);
6641 int ind = strlen(buf)-1;
6642 int x2 = combo_preview_text2.x;
6643 if(x2 + text_length(txfont, buf) > zq_screen_w-2)
6644 {
6645 auto dotlen = text_length(txfont, "..");
6646 x2 += dotlen;
6647 while(x2 + text_length(txfont, buf) > zq_screen_w-2)
6648 {
6649 if(ind < 0) break;
6650 buf[ind--] = '\0';
6651 }
6652 while(ind >= 0 && buf[ind] == ' ')
6653 buf[ind--] = 0; //trim spaces
6654 strcat(buf, "..");
6655 }
6656
6657 sprintf(shortbuf, "Cycle: %d\nCSet: %d\n%s", NextCombo, NextCSet, buf);
6658 textbox_out(screen,txfont,combo_preview_text2.x,combo_preview_text2.y,jwin_pal[jcBOXFG],jwin_pal[jcBOX],shortbuf,0,&combo_preview_text2);
6659 }
6660 }
6661
6662 font = get_zc_font(font_lfont_l);
6663 bool merged = is_compact ? compact_merged_combopane : large_merged_combopane;
6664 draw_text_button(screen,combo_merge_btn.x,combo_merge_btn.y,combo_merge_btn.w,combo_merge_btn.h,merged ? "<|>" : ">|<",vc(1),vc(14),0,true);
6665 }
6666 break;
6667 case rFAVORITES:
6668 {
6669 font = get_zc_font(font_lfont_l);
6670
6671 jwin_draw_frame(screen,favorites_window.x,favorites_window.y,favorites_window.w,favorites_window.h, FR_WIN);
6672 rectfill(screen,favorites_window.x+2,favorites_window.y+2,favorites_window.x+favorites_window.w-3,favorites_window.y+favorites_window.h-3,jwin_pal[jcBOX]);
6673 jwin_draw_frame(screen,favorites_list.x-2,favorites_list.y-2,(favorites_list.w*favorites_list.xscale)+4,(favorites_list.h*favorites_list.yscale)+4, FR_DEEP);
6674 rectfill(screen,favorites_list.x,favorites_list.y,favorites_list.x+(favorites_list.w*favorites_list.xscale)-1,favorites_list.y+(favorites_list.h*favorites_list.yscale)-1,jwin_pal[jcBOXFG]);
6675
6676 textprintf_ex(screen,get_zc_font(font_lfont_l),favorites_list.x-2,favorites_list.y-15,jwin_pal[jcBOXFG],-1,is_compact ? "Favorites" : "Favorite Combos");
6677 BITMAP* subb = create_bitmap_ex(8,16,16);
6678
6679 for(int32_t col=0; col<favorites_list.w; ++col)
6680 {
6681 for(int32_t row=0; row<favorites_list.h; ++row)
6682 {
6683 auto i = (row*FAVORITECOMBO_PER_ROW)+col+FAVORITECOMBO_PER_PAGE*FavoriteComboPage;
6684 auto& sqr = favorites_list.subsquare(col,row);
6685 if(i >= MAXFAVORITECOMBOS || favorite_combos[i]==-1)
6686 {
6687 if (InvalidBG == 2)
6688 {
6689 draw_checkerboard(screen, sqr.x, sqr.y, sqr.w);
6690 }
6691 else if(InvalidBG == 1)
6692 {
6693 draw_static_pos(sqr);
6694 }
6695 else
6696 {
6697 xout(screen, sqr.x, sqr.y, sqr.x+sqr.w-1, sqr.y+sqr.h-1, vc(15), vc(0));
6698 }
6699 }
6700 else
6701 {
6702 clear_bitmap(subb);
6703 bool repos = combotile_override_x < 0 && combotile_override_y < 0;
6704
6705 switch(favorite_combo_modes[i])
6706 {
6707 case dm_alias:
6708 draw_combo_alias_thumbnail(subb, &combo_aliases[favorite_combos[i]], 0, 0, 1);
6709 if (ShowFavoriteComboModes)
6710 put_engraving(subb, 0, 0, 0x3E, 1);
6711 break;
6712 case dm_cpool:
6713 {
6714 int32_t cid = -1; int8_t cs = CSet;
6715 combo_pool const& cp = combo_pools[favorite_combos[i]];
6716
6717 if (cp.get_w(cid, cs, 0) && !combobuf[cid].tile)
6718 cid = -1; //no tile to draw
6719 put_combo(subb, 0, 0, cid, cs, 0, 0);
6720 if (ShowFavoriteComboModes)
6721 put_engraving(subb, 0, 0, 0x3D, 1);
6722 break;
6723 }
6724 case dm_auto:
6725 {
6726 int32_t cid = -1; int8_t cs = CSet;
6727 combo_auto const& ca = combo_autos[favorite_combos[i]];
6728
6729 cid = ca.getDisplay();
6730 if (cid == 0)
6731 cid = -1;
6732 put_combo(subb, 0, 0, cid, cs, 0, 0);
6733 if (ShowFavoriteComboModes)
6734 put_engraving(subb, 0, 0, 0x3C, 1);
6735 break;
6736 }
6737 default:
6738 if (repos)
6739 {
6740 combotile_override_x = sqr.x + (sqr.w - 16) / 2;
6741 combotile_override_y = sqr.y + (sqr.h - 16) / 2;
6742 }
6743 put_combo(subb, 0, 0, favorite_combos[i], CSet, Flags & (cFLAGS | cWALK), 0);
6744 if (repos) combotile_override_x = combotile_override_y = -1;
6745 }
6746 stretch_blit(subb, screen, 0, 0, 16, 16, sqr.x, sqr.y, sqr.w, sqr.h);
6747 }
6748 }
6749 }
6750
6751 destroy_bitmap(subb);
6752
6753 bool zoomed = is_compact ? compact_zoomed_fav : large_zoomed_fav;
6754 if(!is_compact)
6755 textprintf_right_ex(screen, get_zc_font(font_lfont_l), favorites_pgleft.x - 2, favorites_pgleft.y, jwin_pal[jcBOXFG], -1, "%d/9", FavoriteComboPage + 1);
6756
6757 draw_text_button(screen, favorites_pgleft.x, favorites_pgleft.y, favorites_pgleft.w, favorites_pgleft.h, is_compact ? "<" : "<-", vc(1), vc(14), 0, true);
6758 draw_text_button(screen, favorites_pgright.x, favorites_pgright.y, favorites_pgright.w, favorites_pgright.h, is_compact ? ">" : "->", vc(1), vc(14), 0, true);
6759 draw_text_button(screen,favorites_zoombtn.x,favorites_zoombtn.y,favorites_zoombtn.w,favorites_zoombtn.h,zoomed ? "-" : "+",vc(1),vc(14),0,true);
6760 draw_text_button(screen,favorites_x.x,favorites_x.y,favorites_x.w,favorites_x.h,"X",vc(1),vc(14),0,true);
6761 draw_text_button(screen,favorites_infobtn.x,favorites_infobtn.y,favorites_infobtn.w,favorites_infobtn.h,"?",vc(1),vc(14),0,true);
6762 }
6763 break;
6764 case rCOMMANDS:
6765 {
6766 jwin_draw_frame(screen,commands_window.x,commands_window.y,commands_window.w,commands_window.h, FR_WIN);
6767 rectfill(screen,commands_window.x+2,commands_window.y+2,commands_window.x+commands_window.w-3,commands_window.y+commands_window.h-3,jwin_pal[jcBOX]);
6768 jwin_draw_frame(screen,commands_list.x-2,commands_list.y-2,(commands_list.w*commands_list.xscale)+4,(commands_list.h*commands_list.yscale)+4, FR_DEEP);
6769 rectfill(screen,commands_list.x,commands_list.y,commands_list.x+(commands_list.w*commands_list.xscale)-1,commands_list.y+(commands_list.h*commands_list.yscale)-1,jwin_pal[jcBOXFG]);
6770 font=get_custom_font(CFONT_FAVCMD);
6771
6772 for(int32_t cmd=0; cmd<(commands_list.w*commands_list.h); ++cmd)
6773 {
6774 uint hkey = favorite_commands[cmd];
6775 draw_layer_button(screen,
6776 (cmd%commands_list.w)*commands_list.xscale+commands_list.x,
6777 (cmd/commands_list.w)*commands_list.yscale+commands_list.y,
6778 commands_list.xscale,
6779 commands_list.yscale,
6780 get_hotkey_name(hkey),
6781 (selected_hotkey(hkey)?D_SELECTED:0) | (disabled_hotkey(hkey)?D_DISABLED:0));
6782 }
6783
6784 font = get_zc_font(font_lfont_l);
6785 if(commands_txt.x > 0)
6786 {
6787 gui_textout_ln(screen, get_zc_font(font_lfont_l), (ucc*)"Favorite Commands", commands_txt.x, commands_txt.y, jwin_pal[jcBOXFG], -1, 0);
6788 }
6789
6790 bool zoomed = is_compact ? compact_zoomed_cmd : large_zoomed_cmd;
6791 draw_text_button(screen,commands_zoombtn.x,commands_zoombtn.y,commands_zoombtn.w,commands_zoombtn.h,zoomed ? "-" : "+",vc(1),vc(14),0,true);
6792 draw_text_button(screen,commands_x.x,commands_x.y,commands_x.w,commands_x.h,"X",vc(1),vc(14),0,true);
6793 draw_text_button(screen,commands_infobtn.x,commands_infobtn.y,commands_infobtn.w,commands_infobtn.h,"?",vc(1),vc(14),0,true);
6794 }
6795 break;
6796 }
6797 font = tfont;
6798 }
6799
6800 bool pause_refresh = true;
6801 bool is_refreshing = false;
6802 11 void refresh(int32_t flags, bool update)
6803 {
6804
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(pause_refresh) return;
6805 static bool refreshing = false;
6806
6807 int num_screens_to_draw = Map.getViewSize();
6808
6809 bool earlyret = refreshing;
6810 is_refreshing = refreshing = true;
6811 //^ These prevent recursive calls from updating the screen early
6812
6813 bool zoom_delay = (zoomed_minimap && flags != rSCRMAP);
6814 if(zoom_delay)
6815 flags &= ~rSCRMAP;
6816
6817 if(flags&rCLEAR)
6818 {
6819 //magic pink = 0xED
6820 //system black = vc(0)
6821 //Clear a4 menu
6822 // clear_to_color(screen,jwin_pal[jcBOX]);
6823 clear_to_color(screen,0);
6824
6825 //Clears should refresh everything!
6826 flags |= rALL;
6827 }
6828
6829 if(flags&rSCRMAP)
6830 draw_screenunit(rSCRMAP,flags);
6831
6832 if(flags&rMAP)
6833 draw_screenunit(rMAP,flags);
6834
6835 if((flags&rCOMBOS) || (draw_mode == dm_cpool && (flags&rFAVORITES)))
6836 draw_screenunit(rCOMBOS,flags);
6837
6838 if(flags&(rCOMBO|rCOMBOS))
6839 draw_screenunit(rCOMBO,flags);
6840
6841 if(flags&rMENU)
6842 drawpanel();
6843
6844 if(flags&rFAVORITES)
6845 draw_screenunit(rFAVORITES,flags);
6846
6847 if(flags&rCOMMANDS)
6848 draw_screenunit(rCOMMANDS,flags);
6849
6850 FONT* tfont = font;
6851 font = get_custom_font(CFONT_GUI);
6852 jwin_draw_frame(screen,layer_panel.x,layer_panel.y,layer_panel.w,layer_panel.h,FR_DEEP);
6853 rectfill(screen,layer_panel.x,layer_panel.y,layer_panel.x+layer_panel.w-1,layer_panel.y+layer_panel.h-1,jwin_pal[jcBOX]);
6854
6855 for(int32_t i=0; i<=6; ++i)
6856 {
6857 char tbuf[15];
6858
6859 if (i>0 && mapscreen_valid_layers[i - 1] && num_screens_to_draw == 1)
6860 {
6861 if(is_compact)
6862 sprintf(tbuf, "%s%d %d:%02X", (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"", i, Map.CurrScr()->layermap[i-1], Map.CurrScr()->layerscreen[i-1]);
6863 else sprintf(tbuf, "%s%d (%d:%02X)", (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"", i, Map.CurrScr()->layermap[i-1], Map.CurrScr()->layerscreen[i-1]);
6864 }
6865 else
6866 {
6867 sprintf(tbuf, "%s%d", (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"", i);
6868 }
6869
6870 int32_t spacing_offs = is_compact ? 2 : 10;
6871 int32_t rx = (i * (layerpanel_buttonwidth+spacing_offs+layerpanel_checkbox_wid)) + layer_panel.x+(is_compact?2:6);
6872 int32_t ry = layer_panel.y;
6873 auto cbyofs = (layerpanel_buttonheight-layerpanel_checkbox_hei)/2;
6874 draw_layer_button(screen, rx, ry, layerpanel_buttonwidth, layerpanel_buttonheight, tbuf, CurrentLayer==i? D_SELECTED : ( i > 0 && !mapscreen_valid_layers[i-1]) ? D_DISABLED : 0);
6875 draw_checkbox(screen,rx+layerpanel_buttonwidth+1,ry+cbyofs,layerpanel_checkbox_wid,layerpanel_checkbox_hei,LayerMaskInt[i]!=0);
6876 }
6877
6878 font=tfont;
6879
6880 // } //if(true)
6881 if(zq_showpal)
6882 {
6883 for(int32_t i=0; i<256; i++)
6884 {
6885 rectfill(screen,((i&15)<<2)+256,((i>>4)<<2)+176,((i&15)<<2)+259,((i>>4)<<2)+179,i);
6886 }
6887 }
6888 { //Show top-left info
6889 size_t maxwid = (mapscreen_screenunit_scale*mapscreenbmp->w)-1;
6890 size_t maxhei = (mapscreen_screenunit_scale*mapscreenbmp->w);
6891 set_clip_rect(screen,mapscreen_x,mapscreen_y,mapscreen_x+maxwid-1,mapscreen_y+maxhei-1);
6892 FONT* showfont = get_custom_font(CFONT_INFO);
6893 int showfont_h = text_height(showfont);
6894 int32_t ypos = mapscreen_y;
6895 if(prv_mode)
6896 {
6897 textout_shadowed_ex(screen,showfont,"Preview Mode",0,ypos,vc(15),vc(0),infobg?vc(0):-1);
6898 ypos += showfont_h+1;
6899 if(prv_twon)
6900 {
6901 textprintf_shadowed_ex(screen,showfont,0,ypos,vc(15),vc(0),infobg?vc(0):-1,"T Warp=%d tics", Map.get_prvtime());
6902 ypos += showfont_h+1;
6903 }
6904 }
6905 if(ShowFPS)
6906 {
6907 textprintf_shadowed_ex(screen,showfont,0,ypos,vc(15),vc(0),infobg?vc(0):-1,"FPS: %3d",lastfps);
6908 ypos += showfont_h+1;
6909 }
6910
6911 if(ShowFFScripts && !prv_mode)
6912 {
6913 word num_ffcs = Map.CurrScr()->numFFC();
6914 for(word i=0; i< num_ffcs; i++)
6915 {
6916 if(ypos+showfont_h-1 > map_page_bar[0].y)
6917 break;
6918 if(Map.CurrScr()->ffcs[i].script && Map.CurrScr()->ffcs[i].data)
6919 {
6920 textout_shadowed_ex(screen, showfont, ffcmap[Map.CurrScr()->ffcs[i].script-1].scriptname.substr(0,300).c_str(),0,ypos,vc(showxypos_ffc==i ? 14 : 15),vc(0),infobg?vc(0):-1);
6921 ypos+=showfont_h+1;
6922 }
6923 }
6924 }
6925 clear_clip_rect(screen);
6926 if(prv_mode)
6927 do_previewtext();
6928 }
6929 // Show Errors & Details
6930 //This includes the presence of: Screen State Carryover, Timed Warp, Maze Path, the 'Sideview Gravity', 'Invisible Hero',
6931 //'Save Screen', 'Continue Here' and 'Treat As..' Screen Flags,
6932 // the String, every Room Type and Catch All, and all four Tile and Side Warps.
6933 if(!prv_mode && ShowInfo)
6934 {
6935 int32_t i=0;
6936 char buf[2048];
6937
6938 // Start with general information
6939 if(Map.CurrScr()->flags3&fINVISHERO)
6940 {
6941 sprintf(buf,"Invisible Hero");
6942 show_screen_error(buf,i++,vc(15));
6943 }
6944
6945 if(Map.getLayerTargetMap() > 0)
6946 {
6947 Map.setlayertarget(); //Now the text does not carry over when changing maps, but shifting back, it does not **re-appear** until you change screens.
6948 //It was also required to set some updates in onDecMap and onIncMap. #
6949 //This fixes Screen Info not displaying properly when changing maps. -Z
6950 //Needed to refresh the screen info. -Z ( 26th March, 2019 )
6951 int32_t m = Map.getLayerTargetMultiple();
6952 sprintf(buf,"Used as a layer by screen %d:%02X",Map.getLayerTargetMap(),Map.getLayerTargetScr());
6953 char buf2[24];
6954
6955 if(m>0)
6956 {
6957 sprintf(buf2," and %d other%s",m,m>1?"s":"");
6958 strcat(buf,buf2);
6959 }
6960
6961 show_screen_error(buf,i++,vc(15));
6962 }
6963
6964 if(Map.CurrScr()->nextmap)
6965 {
6966 sprintf(buf,"Screen State carries over to %d:%02X",Map.CurrScr()->nextmap,Map.CurrScr()->nextscr);
6967 show_screen_error(buf,i++,vc(15));
6968 }
6969
6970 if(Map.CurrScr()->timedwarptics)
6971 {
6972 sprintf(buf,"%s%sTimed Warp: %s",(Map.CurrScr()->flags4&fTIMEDDIRECT)?"Direct ":"",(Map.CurrScr()->flags5&fRANDOMTIMEDWARP)?"Random ":"",ticksstr(Map.CurrScr()->timedwarptics));
6973 show_screen_error(buf,i++,vc(15));
6974 }
6975
6976 if(Map.CurrScr()->flags&fMAZE)
6977 {
6978 sprintf(buf,"Maze Path: %s (Exit %s)",pathstr(Map.CurrScr()->path),mazedirstr[Map.CurrScr()->exitdir]);
6979 show_screen_error(buf,i++,vc(15));
6980 }
6981
6982 bool continuescreen = false, savecombo = false;
6983
6984 if(Map.CurrScr()->flags4&fAUTOSAVE)
6985 {
6986 sprintf(buf,"Automatic Save%s Screen", (Map.CurrScr()->flags6&fCONTINUEHERE) ? "-Continue":"");
6987 show_screen_error(buf,i++,vc(15));
6988 continuescreen = ((Map.CurrScr()->flags6&fCONTINUEHERE)!=0);
6989 savecombo = true;
6990 }
6991 else if(Map.CurrScr()->flags6&fCONTINUEHERE)
6992 {
6993 sprintf(buf,"Continue Screen");
6994 show_screen_error(buf,i++,vc(15));
6995 continuescreen = true;
6996 }
6997
6998 if(isSideViewGravity())
6999 {
7000 sprintf(buf,"Sideview Gravity");
7001 show_screen_error(buf,i++,vc(15));
7002 }
7003
7004 if(Map.CurrScr()->flags6 & (fCAVEROOM|fDUNGEONROOM))
7005 {
7006 sprintf(buf,"Treat As %s%s Screen", (Map.CurrScr()->flags6&fCAVEROOM) ? "Interior":"NES Dungeon",
7007 (Map.CurrScr()->flags6 & (fCAVEROOM|fDUNGEONROOM)) == (fCAVEROOM|fDUNGEONROOM) ? " or NES Dungeon":"");
7008 show_screen_error(buf,i++,vc(15));
7009 }
7010
7011 if(Map.CurrScr()->oceansfx != 0)
7012 {
7013 sprintf(buf,"Ambient Sound: %s",sfx_string[Map.CurrScr()->oceansfx]);
7014 show_screen_error(buf,i++,vc(15));
7015 }
7016
7017 if(Map.CurrScr()->bosssfx != 0)
7018 {
7019 sprintf(buf,"Boss Roar Sound: %s",sfx_string[Map.CurrScr()->bosssfx]);
7020 show_screen_error(buf,i++,vc(15));
7021 }
7022
7023 if(Map.CurrScr()->str)
7024 {
7025 strncpy(buf,MsgString(Map.CurrScr()->str, true, false),72);
7026 buf[72] = '\0';
7027 char shortbuf[72];
7028 strip_extra_spaces(buf);
7029 shorten_string(shortbuf, buf, get_zc_font(font_lfont_l), 72, 280);
7030 sprintf(buf,"String %s",shortbuf);
7031 show_screen_error(buf,i++,vc(15));
7032 }
7033
7034 if((Map.CurrScr()->flags&fWHISTLE) || (Map.CurrScr()->flags7&fWHISTLEWATER))
7035 {
7036 sprintf(buf,"Whistle ->%s%s%s",(Map.CurrScr()->flags&fWHISTLE)?" Stairs":"",
7037 (Map.CurrScr()->flags&fWHISTLE && Map.CurrScr()->flags7&fWHISTLEWATER)?", ":"",
7038 (Map.CurrScr()->flags7&fWHISTLEWATER)?"Dry Lake":"");
7039 show_screen_error(buf,i++,vc(15));
7040 }
7041
7042 switch(Map.CurrScr()->room)
7043 {
7044 case rSP_ITEM:
7045 sprintf(buf,"Special Item is %s",item_string[Map.CurrScr()->catchall]);
7046 show_screen_error(buf,i++, vc(15));
7047 break;
7048
7049 case rINFO:
7050 {
7051 int32_t shop = Map.CurrScr()->catchall;
7052 sprintf(buf,"Pay For Info: -%d, -%d, -%d",
7053 QMisc.info[shop].price[0],QMisc.info[shop].price[1],QMisc.info[shop].price[2]);
7054 show_screen_error(buf,i++, vc(15));
7055 }
7056 break;
7057
7058 case rMONEY:
7059 sprintf(buf,"Secret Money: %d Rupees",Map.CurrScr()->catchall);
7060 show_screen_error(buf,i++, vc(15));
7061 break;
7062
7063 case rGAMBLE:
7064 show_screen_error("Gamble Room",i++, vc(15));
7065 break;
7066
7067 case rREPAIR:
7068 sprintf(buf,"Door Repair: -%d Rupees",Map.CurrScr()->catchall);
7069 show_screen_error(buf,i++, vc(15));
7070 break;
7071
7072 case rRP_HC:
7073 sprintf(buf,"Take %s or %s", item_string[iRPotion], item_string[iHeartC]);
7074 show_screen_error(buf,i++, vc(15));
7075 break;
7076
7077 case rGRUMBLE:
7078 show_screen_error("Feed the Goriya",i++, vc(15));
7079 break;
7080
7081 case rTRIFORCE:
7082 show_screen_error("Triforce Check",i++, vc(15));
7083 break;
7084
7085 case rP_SHOP:
7086 case rSHOP:
7087 {
7088 int32_t shop = Map.CurrScr()->catchall;
7089 sprintf(buf,"%sShop: ",
7090 Map.CurrScr()->room==rP_SHOP ? "Potion ":"");
7091
7092 for(int32_t j=0; j<3; j++) if(QMisc.shop[shop].item[j]>0) // Print the 3 items and prices
7093 {
7094 strcat(buf,item_string[QMisc.shop[shop].item[j]]);
7095 strcat(buf,":");
7096 char pricebuf[8];
7097 sprintf(pricebuf,"%d",QMisc.shop[shop].price[j]);
7098 strcat(buf,pricebuf);
7099
7100 if(j<2 && QMisc.shop[shop].item[j+1]>0) strcat(buf,", ");
7101 }
7102
7103 show_screen_error(buf,i++, vc(15));
7104 }
7105 break;
7106
7107 case rBOTTLESHOP:
7108 {
7109 int32_t shop = Map.CurrScr()->catchall;
7110 sprintf(buf,"Bottle Shop: ");
7111
7112 for(int32_t j=0; j<3; j++) if(QMisc.bottle_shop_types[shop].fill[j]>0) // Print the 3 fills and prices
7113 {
7114 strcat(buf,QMisc.bottle_types[QMisc.bottle_shop_types[shop].fill[j]-1].name);
7115 strcat(buf,":");
7116 char pricebuf[8];
7117 sprintf(pricebuf,"%d",QMisc.bottle_shop_types[shop].price[j]);
7118 strcat(buf,pricebuf);
7119
7120 if(j<2 && QMisc.bottle_shop_types[shop].fill[j+1]>0) strcat(buf,", ");
7121 }
7122
7123 show_screen_error(buf,i++, vc(15));
7124 }
7125 break;
7126
7127 case rTAKEONE:
7128 {
7129 int32_t shop = Map.CurrScr()->catchall;
7130 sprintf(buf,"Take Only One: %s%s%s%s%s",
7131 QMisc.shop[shop].item[0]<1?"":item_string[QMisc.shop[shop].item[0]],QMisc.shop[shop].item[0]>0?", ":"",
7132 QMisc.shop[shop].item[1]<1?"":item_string[QMisc.shop[shop].item[1]],(QMisc.shop[shop].item[1]>0&&QMisc.shop[shop].item[2]>0)?", ":"",
7133 QMisc.shop[shop].item[2]<1?"":item_string[QMisc.shop[shop].item[2]]);
7134 show_screen_error(buf,i++, vc(15));
7135 }
7136 break;
7137
7138 case rBOMBS:
7139 sprintf(buf,"More Bombs: -%d Rupees",Map.CurrScr()->catchall);
7140 show_screen_error(buf,i++, vc(15));
7141 break;
7142
7143 case rARROWS:
7144 sprintf(buf,"More Arrows: -%d Rupees",Map.CurrScr()->catchall);
7145 show_screen_error(buf,i++, vc(15));
7146 break;
7147
7148 case rSWINDLE:
7149 sprintf(buf,"Leave Life or %d Rupees",Map.CurrScr()->catchall);
7150 show_screen_error(buf,i++, vc(15));
7151 break;
7152
7153 case r10RUPIES:
7154 show_screen_error("10 Rupees",i++, vc(15));
7155 break;
7156
7157 case rGANON:
7158 show_screen_error("Ganon Room",i++, vc(15));
7159 break;
7160
7161 case rZELDA:
7162 show_screen_error("Zelda Room",i++, vc(15));
7163 break;
7164
7165 case rMUPGRADE:
7166 show_screen_error("1/2 Magic Upgrade",i++, vc(15));
7167 break;
7168
7169 case rLEARNSLASH:
7170 show_screen_error("Learn Slash",i++, vc(15));
7171 break;
7172
7173 case rWARP:
7174 sprintf(buf,"3-Stair Warp: Warp Ring %d",Map.CurrScr()->catchall);
7175 show_screen_error(buf,i++, vc(15));
7176 break;
7177 }
7178
7179 bool undercombo = false, warpa = false, warpb = false, warpc = false, warpd = false, warpr = false;
7180
7181 word num_ffcs = Map.CurrScr()->numFFC();
7182 for(int32_t c=0; c<176+128+1+num_ffcs; ++c)
7183 {
7184 // Checks both combos, secret combos, undercombos and FFCs
7185 //Fixme:
7186 int32_t ctype =
7187 combobuf[vbound(
7188 (c>=305 ? Map.CurrScr()->ffcs[c-305].data :
7189 c>=304 ? Map.CurrScr()->undercombo :
7190 c>=176 ? Map.CurrScr()->secretcombo[c-176] :
7191 !Map.CurrScr()->valid ? 0 : // Sanity check: does room combo data exist?
7192 Map.CurrScr()->data[c]
7193 ), 0, MAXCOMBOS-1)].type;
7194
7195 if(!undercombo && integrityBoolUnderCombo(Map.CurrScr(),ctype))
7196 {
7197 undercombo = true;
7198 show_screen_error("Under Combo is combo 0",i++, vc(7));
7199 }
7200
7201 // Tile Warp types
7202 switch(ctype)
7203 {
7204 case cSAVE:
7205 case cSAVE2:
7206 if(!savecombo)
7207 {
7208 savecombo = true;
7209
7210 if(integrityBoolSaveCombo(Map.CurrScr(),ctype))
7211 show_screen_error("Save Screen",i++, vc(15));
7212 else
7213 show_screen_error("Save-Continue Screen",i++, vc(15));
7214 }
7215
7216 break;
7217
7218 case cSTAIRR:
7219 case cPITR:
7220 case cSWARPR:
7221 if(!warpr && (Map.CurrScr()->tilewarptype[0]==wtCAVE || Map.CurrScr()->tilewarptype[1]==wtCAVE ||
7222 Map.CurrScr()->tilewarptype[2]==wtCAVE || Map.CurrScr()->tilewarptype[3]==wtCAVE))
7223 {
7224 warpr = true;
7225 show_screen_error("Random Tile Warp contains Cave/Item Cellar",i++, vc(7));
7226 }
7227
7228 break;
7229
7230 case cCAVED:
7231 case cPITD:
7232 case cSTAIRD:
7233 case cCAVE2D:
7234 case cSWIMWARPD:
7235 case cDIVEWARPD:
7236 case cSWARPD:
7237 if(!warpd)
7238 {
7239 warpd = true;
7240 tile_warp_notification(3,buf);
7241 show_screen_error(buf,i++, vc(15));
7242 }
7243
7244 break;
7245
7246 case cCAVEC:
7247 case cPITC:
7248 case cSTAIRC:
7249 case cCAVE2C:
7250 case cSWIMWARPC:
7251 case cDIVEWARPC:
7252 case cSWARPC:
7253 if(!warpc)
7254 {
7255 warpc = true;
7256 tile_warp_notification(2,buf);
7257 show_screen_error(buf,i++, vc(15));
7258 }
7259
7260 break;
7261
7262 case cCAVEB:
7263 case cPITB:
7264 case cSTAIRB:
7265 case cCAVE2B:
7266 case cSWIMWARPB:
7267 case cDIVEWARPB:
7268 case cSWARPB:
7269 if(!warpb)
7270 {
7271 warpb = true;
7272 tile_warp_notification(1,buf);
7273 show_screen_error(buf,i++, vc(15));
7274 }
7275
7276 break;
7277
7278 case cCAVE:
7279 case cPIT:
7280 case cSTAIR:
7281 case cCAVE2:
7282 case cSWIMWARP:
7283 case cDIVEWARP:
7284 case cSWARPA:
7285 if(!warpa)
7286 {
7287 warpa = true;
7288 tile_warp_notification(0,buf);
7289 show_screen_error(buf,i++, vc(15));
7290 }
7291
7292 break;
7293 }
7294 }
7295
7296 int32_t sidewarpnotify = 0;
7297
7298 if(Map.CurrScr()->flags2&wfUP)
7299 {
7300 side_warp_notification(Map.CurrScr()->sidewarpindex&3,0,buf);
7301 show_screen_error(buf,i++, vc(15));
7302 sidewarpnotify|=(1<<(Map.CurrScr()->sidewarpindex&3));
7303 }
7304
7305 if(Map.CurrScr()->flags2&wfDOWN)
7306 {
7307 side_warp_notification((Map.CurrScr()->sidewarpindex>>2)&3,1,buf);
7308 show_screen_error(buf,i++, vc(15));
7309 sidewarpnotify|=(1<<((Map.CurrScr()->sidewarpindex>>2)&3));
7310 }
7311
7312 if(Map.CurrScr()->flags2&wfLEFT)
7313 {
7314 side_warp_notification((Map.CurrScr()->sidewarpindex>>4)&3,2,buf);
7315 show_screen_error(buf,i++, vc(15));
7316 sidewarpnotify|=(1<<((Map.CurrScr()->sidewarpindex>>4)&3));
7317 }
7318
7319 if(Map.CurrScr()->flags2&wfRIGHT)
7320 {
7321 side_warp_notification((Map.CurrScr()->sidewarpindex>>6)&3,3,buf);
7322 show_screen_error(buf,i++, vc(15));
7323 sidewarpnotify|=(1<<((Map.CurrScr()->sidewarpindex>>6)&3));
7324 }
7325
7326 if(!(sidewarpnotify&1) && Map.CurrScr()->timedwarptics)
7327 {
7328 side_warp_notification(0,4,buf); // Timed Warp
7329 show_screen_error(buf,i++, vc(15));
7330 }
7331
7332 // Now for errors
7333 if((Map.CurrScr()->flags4&fSAVEROOM) && !savecombo) show_screen_error("Save Point->Continue Here, but no Save Point combo?",i++, vc(14));
7334
7335 if(integrityBoolEnemiesItem(Map.CurrScr())) show_screen_error("Enemies->Item, but no enemies",i++, vc(7));
7336
7337 if(integrityBoolEnemiesSecret(Map.CurrScr())) show_screen_error("Enemies->Secret, but no enemies",i++, vc(7));
7338
7339 if(integrityBoolGuyNoString(Map.CurrScr())) show_screen_error("Non-Fairy Guy, but String is (none)",i++, vc(14));
7340
7341 if(integrityBoolRoomNoGuy(Map.CurrScr())) show_screen_error("Guy is (none)",i++, vc(14));
7342
7343 if(integrityBoolRoomNoString(Map.CurrScr())) show_screen_error("String is (none)",i++, vc(14));
7344
7345 if(integrityBoolRoomNoGuyNoString(Map.CurrScr())) show_screen_error("Guy and String are (none)",i++, vc(14));
7346 }
7347
7348 if(zoom_delay)
7349 draw_screenunit(rSCRMAP,flags);
7350
7351 if(earlyret)
7352 return;
7353
7354 //Draw the Main Menu
7355 rectfill(screen,mainbar.x,mainbar.y,mainbar.x+mainbar.w-1,mainbar.y+mainbar.h-1,jwin_pal[jcBOX]);
7356 jwin_draw_frame(screen,mainbar.x,mainbar.y,mainbar.w,mainbar.h,FR_WIN);
7357
7358 FONT* oldfont = font;
7359 font = get_custom_font(CFONT_GUI);
7360
7361 //Drawmode button
7362 draw_text_button(screen,drawmode_btn.x,drawmode_btn.y,drawmode_btn.w,drawmode_btn.h,dm_names[draw_mode],vc(1),vc(14),0,true);
7363 //Compact button
7364 draw_text_button(screen,compactbtn.x, compactbtn.y, compactbtn.w, compactbtn.h, is_compact ? "< Expand" : "> Compact", vc(1),vc(14),0,true);
7365 //Zoom buttons
7366 zoom_in_btn_disabled = num_screens_to_draw == 1;
7367 zoom_out_btn_disabled = num_screens_to_draw == mapscreen_num_screens_to_draw_max;
7368 draw_text_button(screen,zoominbtn.x, zoominbtn.y, zoominbtn.w, zoominbtn.h, "+", vc(1),vc(14),zoom_in_btn_disabled ? D_DISABLED : 0,true);
7369 draw_text_button(screen,zoomoutbtn.x, zoomoutbtn.y, zoomoutbtn.w, zoomoutbtn.h, "-", vc(1),vc(14),zoom_out_btn_disabled ? D_DISABLED : 0,true);
7370
7371 font = oldfont;
7372
7373 d_nbmenu_proc(MSG_DRAW, &dialogs[0], 0);
7374
7375 ComboBrushPause=0;
7376
7377 if(update)
7378 custom_vsync();
7379 is_refreshing = refreshing = false;
7380 11 }
7381
7382 12 static int minimap_tooltip_id = ttip_register_id();
7383
7384 void select_scr()
7385 {
7386 if(Map.getCurrMap()>=Map.getMapCount())
7387 return;
7388
7389 int32_t tempcb=ComboBrush;
7390 ComboBrush=0;
7391
7392 size_and_pos const& real_mini = zoomed_minimap ? real_minimap_zoomed : real_minimap;
7393
7394 auto prev_cursor = Map.getCursor();
7395 Map.ConfigureCursorHistory(false);
7396
7397 //scooby
7398 while(gui_mouse_b())
7399 {
7400 int32_t x=gui_mouse_x();
7401 int32_t y=gui_mouse_y();
7402
7403 int32_t ind = real_mini.rectind(x,y);
7404
7405 if(ind>=MAPSCRS)
7406 ind-=16;
7407
7408 if(ind > -1 && ind != Map.getCurrScr())
7409 {
7410 Map.setCurrScr(ind);
7411 }
7412
7413 custom_vsync();
7414 refresh(rALL);
7415 }
7416
7417 ComboBrush=tempcb;
7418
7419 Map.ConfigureCursorHistory(true);
7420 if (prev_cursor != Map.getCursor())
7421 Map.pushCursorToHistory(prev_cursor);
7422 }
7423
7424 bool select_favorite()
7425 {
7426 int32_t tempcb=ComboBrush;
7427 ComboBrush=0;
7428 bool valid=false;
7429
7430 while(gui_mouse_b())
7431 {
7432 valid=false;
7433 int32_t x=gui_mouse_x();
7434
7435 if(x<favorites_list.x)
7436 x=favorites_list.x;
7437
7438 if(x>favorites_list.x+(favorites_list.w*favorites_list.xscale)-1)
7439 x=favorites_list.x+(favorites_list.w*favorites_list.xscale)-1;
7440
7441 int32_t y=gui_mouse_y();
7442
7443 if(y<favorites_list.y)
7444 y=favorites_list.y;
7445
7446 if(y>favorites_list.y+(favorites_list.h*favorites_list.yscale)-1)
7447 y=favorites_list.y+(favorites_list.h*favorites_list.yscale)-1;
7448
7449 int32_t tempc=(((y-favorites_list.y)/favorites_list.yscale)*FAVORITECOMBO_PER_ROW)+((x-favorites_list.x)/favorites_list.xscale) + FAVORITECOMBO_PER_PAGE * FavoriteComboPage;
7450
7451 if(tempc >= MAXFAVORITECOMBOS)
7452 {
7453 //Nothing, invalid
7454 }
7455 else
7456 {
7457 if(favorite_combos[tempc]!=-1)
7458 {
7459 switch(favorite_combo_modes[tempc])
7460 {
7461 case dm_alias:
7462 draw_mode = dm_alias;
7463 combo_apos = favorite_combos[tempc];
7464 break;
7465 case dm_cpool:
7466 draw_mode = dm_cpool;
7467 combo_pool_pos = favorite_combos[tempc];
7468 break;
7469 case dm_auto:
7470 draw_mode = dm_auto;
7471 combo_auto_pos = favorite_combos[tempc];
7472 break;
7473 default:
7474 draw_mode = dm_normal;
7475 Combo = favorite_combos[tempc];
7476 }
7477 if(AutoBrush)
7478 BrushWidth = BrushHeight = 1;
7479 valid=true;
7480 fix_drawing_mode_menu();
7481 }
7482 }
7483
7484 custom_vsync();
7485 refresh(rALL);
7486 }
7487
7488 ComboBrush=tempcb;
7489 return valid;
7490 }
7491
7492 void select_combo(int32_t clist)
7493 {
7494 current_combolist=clist;
7495 int32_t tempcb=ComboBrush;
7496 ComboBrush=0;
7497
7498 int autobrush_cx = -1, autobrush_cy = -1;
7499 int autobrush_first = First[current_combolist];
7500 auto& curlist = combolist[current_combolist];
7501 AutoBrushRevert = (key[KEY_ALT]||key[KEY_ALTGR]);
7502 while(gui_mouse_b())
7503 {
7504 int32_t x=gui_mouse_x();
7505
7506 if(x<curlist.x)
7507 x=curlist.x;
7508
7509 if(x>curlist.x+(curlist.w*curlist.xscale)-1)
7510 x=curlist.x+(curlist.w*curlist.xscale)-1;
7511
7512 int32_t y=gui_mouse_y();
7513
7514 if(y<curlist.y)
7515 y=curlist.y;
7516
7517 if(y>curlist.y+(curlist.h*curlist.yscale)-1)
7518 y=curlist.y+(curlist.h*curlist.yscale)-1;
7519
7520 int cx = ((x-curlist.x)/curlist.xscale), cy = ((y-curlist.y)/curlist.yscale);
7521 if(AutoBrush)
7522 {
7523 if(autobrush_cx < 0)
7524 {
7525 autobrush_cx = cx;
7526 autobrush_cy = cy;
7527 }
7528 BrushWidth = vbound(abs(autobrush_cx-cx)+1,1,16);
7529 BrushHeight = vbound(abs(autobrush_cy-cy)+1,1,11);
7530 cx = std::min(autobrush_cx,cx);
7531 cy = std::min(autobrush_cy,cy);
7532 }
7533 Combo=(cy*curlist.w)+cx+First[current_combolist];
7534 custom_vsync();
7535 refresh(rALL);
7536 if(AutoBrush) //Prevent any scrolling
7537 First[current_combolist] = autobrush_first;
7538 }
7539 if(key[KEY_ALT]||key[KEY_ALTGR])
7540 AutoBrushRevert = true;
7541 position_mouse_z(0);
7542 ComboBrush=tempcb;
7543 }
7544
7545 void select_comboa(int32_t clist)
7546 {
7547 current_comboalist=clist;
7548 int32_t tempcb=ComboBrush;
7549 ComboBrush=0;
7550 alias_cset_mod=0;
7551
7552 auto& curlist = comboaliaslist[current_comboalist];
7553 while(gui_mouse_b())
7554 {
7555 int32_t x=gui_mouse_x();
7556
7557 if(x<curlist.x)
7558 x=curlist.x;
7559
7560 if(x>curlist.x+(curlist.w*curlist.xscale)-1)
7561 x=curlist.x+(curlist.w*curlist.xscale)-1;
7562
7563 int32_t y=gui_mouse_y();
7564
7565 if(y<curlist.y)
7566 y=curlist.y;
7567
7568 if(y>curlist.y+(curlist.h*curlist.yscale)-1)
7569 y=curlist.y+(curlist.h*curlist.yscale)-1;
7570
7571 combo_apos=(((y-curlist.y)/curlist.yscale)*curlist.w)+((x-curlist.x)/curlist.xscale)+combo_alistpos[current_comboalist];
7572 custom_vsync();
7573 refresh(rALL);
7574 }
7575
7576 ComboBrush=tempcb;
7577 }
7578
7579 void select_combop(int32_t clist)
7580 {
7581 current_cpoollist=clist;
7582 int32_t tempcb=ComboBrush;
7583 ComboBrush=0;
7584
7585 auto& curlist = comboaliaslist[current_cpoollist];
7586 while(gui_mouse_b())
7587 {
7588 int32_t x=gui_mouse_x();
7589
7590 if(x<curlist.x) x=curlist.x;
7591
7592 if(x>curlist.x+(curlist.w*curlist.xscale)-1)
7593 x=curlist.x+(curlist.w*curlist.xscale)-1;
7594
7595 int32_t y=gui_mouse_y();
7596
7597 if(y<curlist.y) y=curlist.y;
7598
7599 if(y>curlist.y+(curlist.h*curlist.yscale)-1)
7600 y=curlist.y+(curlist.h*curlist.yscale)-1;
7601
7602 combo_pool_pos=(((y-curlist.y)/curlist.yscale)*curlist.w)+((x-curlist.x)/curlist.xscale)+combo_pool_listpos[current_cpoollist];
7603 custom_vsync();
7604 refresh(rALL);
7605 }
7606
7607 ComboBrush=tempcb;
7608 }
7609
7610 void select_autocombo(int32_t clist)
7611 {
7612 current_cautolist = clist;
7613 int32_t tempcb = ComboBrush;
7614 ComboBrush = 0;
7615
7616 auto& curlist = comboaliaslist[current_cautolist];
7617 while (gui_mouse_b())
7618 {
7619 int32_t x = gui_mouse_x();
7620
7621 if (x < curlist.x) x = curlist.x;
7622
7623 if (x > curlist.x + (curlist.w * curlist.xscale) - 1)
7624 x = curlist.x + (curlist.w * curlist.xscale) - 1;
7625
7626 int32_t y = gui_mouse_y();
7627
7628 if (y < curlist.y) y = curlist.y;
7629
7630 if (y > curlist.y + (curlist.h * curlist.yscale) - 1)
7631 y = curlist.y + (curlist.h * curlist.yscale) - 1;
7632
7633 combo_auto_pos = (((y - curlist.y) / curlist.yscale) * curlist.w) + ((x - curlist.x) / curlist.xscale) + combo_auto_listpos[current_cautolist];
7634 cauto_height = combo_autos[combo_auto_pos].getArg() + 1;
7635 custom_vsync();
7636 refresh(rALL);
7637 }
7638
7639 ComboBrush = tempcb;
7640 }
7641
7642 void update_combobrush()
7643 {
7644 clear_bitmap(brushbmp);
7645
7646 if(draw_mode==dm_alias)
7647 {
7648 //int32_t count=(combo_aliases[combo_apos].width+1)*(combo_aliases[combo_apos].height+1)*(comboa_lmasktotal(combo_aliases[combo_apos].layermask));
7649 for(int32_t z=0; z<=comboa_lmasktotal(combo_aliases[combo_apos].layermask); z++)
7650 {
7651 for(int32_t y=0; y<=combo_aliases[combo_apos].height; y++)
7652 {
7653 for(int32_t x=0; x<=combo_aliases[combo_apos].width; x++)
7654 {
7655 int32_t position = ((y*(combo_aliases[combo_apos].width+1))+x)+((combo_aliases[combo_apos].width+1)*(combo_aliases[combo_apos].height+1)*z);
7656
7657 if(combo_aliases[combo_apos].combos[position])
7658 {
7659 if(z==0)
7660 {
7661 putcombo(brushbmp,x<<4,y<<4,combo_aliases[combo_apos].combos[position],wrap(combo_aliases[combo_apos].csets[position]+alias_cset_mod, 0, 13));
7662 }
7663 else
7664 {
7665 overcombo(brushbmp,x<<4,y<<4,combo_aliases[combo_apos].combos[position],wrap(combo_aliases[combo_apos].csets[position]+alias_cset_mod, 0, 13));
7666 }
7667 }
7668 }
7669 }
7670 }
7671
7672 int xoff = 6, yoff = 6;
7673 if(FloatBrush) // Offset the floating pixels, so the 'x' appears centered on the combo still -Em
7674 {
7675 xoff += 2;
7676 yoff += 2;
7677 }
7678 if(alias_origin & 1) // Right-align
7679 xoff += combo_aliases[combo_apos].width*16;
7680 if(alias_origin & 2) // Bottom-align
7681 yoff += combo_aliases[combo_apos].height*16;
7682
7683 textprintf_shadowed_ex(brushbmp, get_zc_font(font_sfont), xoff, yoff, vc(15), vc(0), -1, "x");
7684 }
7685 else if(draw_mode != dm_cpool)
7686 {
7687 int32_t cid = combobrushoverride > -1 ? combobrushoverride : Combo;
7688 int32_t c = 0;
7689
7690 for(int32_t i=0; i<256; i++)
7691 {
7692 if(unsigned(cid+c) >= MAXCOMBOS) break;
7693 if(((i%COMBOS_PER_ROW)<BrushWidth)&&((i/COMBOS_PER_ROW)<BrushHeight))
7694 {
7695 put_combo(brushbmp,(i%COMBOS_PER_ROW)<<4,(i/COMBOS_PER_ROW)<<4,cid+c,CSet,Flags&(cFLAGS|cWALK),0);
7696 }
7697
7698 if(((cid+c)&3)==3)
7699 c+=48;
7700
7701 ++c;
7702
7703 if((i%COMBOS_PER_ROW)==(COMBOS_PER_ROW-1))
7704 c-=256;
7705 }
7706 }
7707 }
7708
7709 byte relational_source_grid[256]=
7710 {
7711 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7712 16, 16, 17, 17, 18, 18, 19, 19, 16, 16, 17, 17, 18, 18, 19, 19,
7713 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
7714 24, 24, 24, 24, 25, 25, 25, 25, 24, 24, 24, 24, 25, 25, 25, 25,
7715 26, 27, 26, 27, 26, 27, 26, 27, 28, 29, 28, 29, 28, 29, 28, 29,
7716 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
7717 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32,
7718 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
7719 34, 35, 36, 37, 34, 35, 36, 37, 34, 35, 36, 37, 34, 35, 36, 37,
7720 38, 38, 39, 39, 38, 38, 39, 39, 38, 38, 39, 39, 38, 38, 39, 39,
7721 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
7722 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
7723 42, 43, 42, 43, 42, 43, 42, 43, 42, 43, 42, 43, 42, 43, 42, 43,
7724 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
7725 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
7726 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46
7727 };
7728
7729 static void draw_autocombo(ComboPosition combo_pos, bool rclick, bool pressframe = false)
7730 {
7731 combo_auto &ca = combo_autos[combo_auto_pos];
7732 int screen = Map.getScreenForPosition(combo_pos);
7733 int pos = combo_pos.truncate();
7734
7735 if (ca.valid())
7736 {
7737 switch (ca.getType())
7738 {
7739 case AUTOCOMBO_BASIC:
7740 {
7741 AutoPattern::autopattern_basic ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7742 if (rclick)
7743 ap.erase(screen, pos);
7744 else
7745 ap.execute(screen, pos);
7746 break;
7747 }
7748 case AUTOCOMBO_Z1:
7749 {
7750 AutoPattern::autopattern_flatmtn ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7751 if (rclick)
7752 ap.erase(screen, pos);
7753 else
7754 ap.execute(screen, pos);
7755 break;
7756 }
7757 case AUTOCOMBO_FENCE:
7758 {
7759 AutoPattern::autopattern_fence ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7760 if (rclick)
7761 ap.erase(screen, pos);
7762 else
7763 ap.execute(screen, pos);
7764 break;
7765 }
7766 case AUTOCOMBO_Z4:
7767 {
7768 AutoPattern::autopattern_cakemtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7769 if (rclick)
7770 ap.erase(screen, pos);
7771 else
7772 ap.execute(screen, pos);
7773 break;
7774 }
7775 case AUTOCOMBO_RELATIONAL:
7776 {
7777 AutoPattern::autopattern_relational ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7778 if (rclick)
7779 ap.erase(screen, pos);
7780 else
7781 ap.execute(screen, pos);
7782 break;
7783 }
7784 case AUTOCOMBO_DGNCARVE:
7785 {
7786 AutoPattern::autopattern_dungeoncarve ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7787 if (rclick)
7788 ap.erase(screen, pos);
7789 else
7790 ap.execute(screen, pos);
7791 break;
7792 }
7793 case AUTOCOMBO_DOR:
7794 {
7795 AutoPattern::autopattern_dormtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7796 if (rclick)
7797 ap.erase(screen, pos);
7798 else
7799 ap.execute(screen, pos);
7800 break;
7801 }
7802 case AUTOCOMBO_TILING:
7803 {
7804 if (pressframe && (key[KEY_LSHIFT] || key[KEY_RSHIFT]))
7805 {
7806 int32_t x = (screen % 16) * 16 + (pos % 16);
7807 int32_t y = (screen / 16) * 11 + (pos / 16);
7808 byte w = (ca.getArg() & 0xF) + 1;
7809 byte h = ((ca.getArg() >> 4) & 0xF) + 1;
7810 ca.setOffsets(x % w, y % h);
7811 }
7812 AutoPattern::autopattern_tiling ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7813 if (rclick)
7814 ap.erase(screen, pos);
7815 else
7816 ap.execute(screen, pos);
7817 break;
7818 }
7819 case AUTOCOMBO_REPLACE:
7820 {
7821 AutoPattern::autopattern_replace ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7822 if (rclick)
7823 ap.erase(screen, pos);
7824 else
7825 ap.execute(screen, pos);
7826 break;
7827 }
7828 case AUTOCOMBO_DENSEFOREST:
7829 {
7830 if (pressframe && (key[KEY_LSHIFT] || key[KEY_RSHIFT]))
7831 {
7832 int32_t x = (screen % 16) * 16 + (pos % 16);
7833 int32_t y = (screen / 16) * 11 + (pos / 16);
7834 ca.setOffsets(x % 2, y % 2);
7835 }
7836 AutoPattern::autopattern_denseforest ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7837 if (rclick)
7838 ap.erase(screen, pos);
7839 else
7840 ap.execute(screen, pos);
7841 break;
7842 }
7843 case AUTOCOMBO_EXTEND:
7844 {
7845 if (CHECK_CTRL_CMD)
7846 break;
7847 AutoPattern::autopattern_extend ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7848 if (rclick)
7849 ap.erase(screen, pos);
7850 else
7851 ap.execute(screen, pos);
7852 break;
7853 }
7854 }
7855 }
7856 else
7857 {
7858 ca.updateValid();
7859 if(!ca.valid())
7860 InfoDialog("Notice", "The autocombo you're trying to use is invalid. Reason:"
7861 + ca.getInvalidReason()).show();
7862 }
7863 }
7864
7865 static void draw_autocombo_command(ComboPosition combo_pos, int32_t cmd = 0, int32_t arg = 0)
7866 {
7867 combo_auto ca = combo_autos[combo_auto_pos];
7868 int screen = Map.getScreenForPosition(combo_pos);
7869 int pos = combo_pos.truncate();
7870
7871 if (ca.valid())
7872 {
7873 switch (ca.getType())
7874 {
7875 case AUTOCOMBO_FENCE:
7876 {
7877 AutoPattern::autopattern_fence ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7878 ap.flip_all_connected(screen, pos, 2048);
7879 break;
7880 }
7881 case AUTOCOMBO_Z4:
7882 {
7883 AutoPattern::autopattern_cakemtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7884 switch (cmd)
7885 {
7886 case 0: // Flip
7887 ap.flip_all_connected(screen, pos, 2048);
7888 break;
7889 case 1: // Grow
7890 ap.resize_connected(screen, pos, 2048, vbound(arg, 1, 9));
7891 break;
7892 }
7893 }
7894 }
7895 }
7896 }
7897
7898 static int32_t get_autocombo_floating_cid(ComboPosition combo_pos, bool clicked)
7899 {
7900 combo_auto& ca = combo_autos[combo_auto_pos];
7901 int screen = Map.getScreenForPosition(combo_pos);
7902 int pos = combo_pos.truncate();
7903 int cid = 0;
7904
7905 if (ca.valid() && Map.isValidPosition(mouse_combo_pos))
7906 {
7907 switch (ca.getType())
7908 {
7909 case AUTOCOMBO_BASIC:
7910 {
7911 AutoPattern::autopattern_basic ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7912 cid = ap.get_floating_cid(screen, pos);
7913 break;
7914 }
7915
7916 case AUTOCOMBO_Z1:
7917 {
7918 AutoPattern::autopattern_flatmtn ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7919 cid = ap.get_floating_cid(screen, pos);
7920 break;
7921 }
7922 case AUTOCOMBO_FENCE:
7923 {
7924 AutoPattern::autopattern_fence ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7925 cid = ap.get_floating_cid(screen, pos);
7926 break;
7927 }
7928 case AUTOCOMBO_Z4:
7929 {
7930 AutoPattern::autopattern_cakemtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7931 cid = ap.get_floating_cid(screen, pos);
7932 break;
7933 }
7934 case AUTOCOMBO_RELATIONAL:
7935 {
7936 AutoPattern::autopattern_relational ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7937 cid = ap.get_floating_cid(screen, pos);
7938 break;
7939 }
7940 case AUTOCOMBO_DGNCARVE:
7941 {
7942 AutoPattern::autopattern_dungeoncarve ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7943 cid = ap.get_floating_cid(screen, pos);
7944 break;
7945 }
7946 case AUTOCOMBO_DOR:
7947 {
7948 AutoPattern::autopattern_dormtn ap(ca.getType(), CurrentLayer, screen, pos, &ca, cauto_height);
7949 cid = ap.get_floating_cid(screen, pos);
7950 break;
7951 }
7952 case AUTOCOMBO_TILING:
7953 {
7954 std::pair<byte, byte> offs = ca.getOffsets();
7955 if (!clicked && (key[KEY_LSHIFT] || key[KEY_RSHIFT]))
7956 {
7957 int32_t x = (screen % 16) * 16 + (pos % 16);
7958 int32_t y = (screen / 16) * 11 + (pos / 16);
7959 byte w = (ca.getArg() & 0xF) + 1;
7960 byte h = ((ca.getArg() >> 4) & 0xF) + 1;
7961 offs.first = (x % w);
7962 offs.second = (y % h);
7963 }
7964 AutoPattern::autopattern_tiling ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7965 cid = ap.get_floating_cid(screen, pos);
7966 break;
7967 }
7968 case AUTOCOMBO_REPLACE:
7969 {
7970 AutoPattern::autopattern_replace ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7971 cid = ap.get_floating_cid(screen, pos);
7972 break;
7973 }
7974 case AUTOCOMBO_DENSEFOREST:
7975 {
7976 AutoPattern::autopattern_denseforest ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7977 cid = ap.get_floating_cid(screen, pos);
7978 break;
7979 }
7980 case AUTOCOMBO_EXTEND:
7981 {
7982 AutoPattern::autopattern_extend ap(ca.getType(), CurrentLayer, screen, pos, &ca);
7983 cid = ap.get_floating_cid(screen, pos);
7984 break;
7985 }
7986 }
7987 }
7988 return cid;
7989 }
7990
7991 void change_autocombo_height(int32_t change)
7992 {
7993 bool can_change = false;
7994 if (draw_mode == dm_auto)
7995 {
7996 combo_auto ca = combo_autos[combo_auto_pos];
7997 switch (ca.getType())
7998 {
7999 case AUTOCOMBO_Z4:
8000 can_change = true;
8001 [[fallthrough]];
8002 case AUTOCOMBO_DOR:
8003 break;
8004 default:
8005 return;
8006 }
8007 }
8008 else
8009 return;
8010
8011 int32_t x = gui_mouse_x();
8012 int32_t y = gui_mouse_y();
8013 double startx = mapscreen_x + (showedges ? (16 * mapscreen_single_scale) : 0);
8014 double starty = mapscreen_y + (showedges ? (16 * mapscreen_single_scale) : 0);
8015 int32_t startxint = mapscreen_x + (showedges ? int32_t(16 * mapscreen_single_scale) : 0);
8016 int32_t startyint = mapscreen_y + (showedges ? int32_t(16 * mapscreen_single_scale) : 0);
8017 ComboPosition pos = get_mapscreen_mouse_combo_pos();
8018
8019 if (can_change && isinRect(x, y, startxint, startyint, int32_t(startx + (256 * mapscreen_single_scale) - 1), int32_t(starty + (176 * mapscreen_single_scale) - 1)))
8020 {
8021 Map.StartListCommand();
8022 draw_autocombo_command(pos, 1, cauto_height + change);
8023 Map.FinishListCommand();
8024 }
8025 cauto_height = vbound(cauto_height + change, 1, 9);
8026 }
8027
8028 void draw(bool justcset)
8029 {
8030 combo_pool const& pool = combo_pools[combo_pool_pos];
8031 if(draw_mode == dm_cpool && !pool.valid())
8032 return;
8033 mark_save_dirty();
8034
8035 refresh(rMAP+rSCRMAP);
8036 ComboPosition last_pos = {-1, -1};
8037
8038 Map.StartListCommand();
8039 bool pressframe = true;
8040 while(gui_mouse_b())
8041 {
8042 int32_t x=gui_mouse_x();
8043 int32_t y=gui_mouse_y();
8044 double startx=mapscreen_x+(showedges?(16*mapscreen_single_scale):0);
8045 double starty=mapscreen_y+(showedges?(16*mapscreen_single_scale):0);
8046 int32_t startxint=mapscreen_x+(showedges?int32_t(16*mapscreen_single_scale):0);
8047 int32_t startyint=mapscreen_y+(showedges?int32_t(16*mapscreen_single_scale):0);
8048 int num_combos_width = 16 * Map.getViewSize();
8049 int num_combos_height = 11 * Map.getViewSize();
8050
8051 if(isinRect(x,y,startxint,startyint,int32_t(startx+(256*mapscreen_screenunit_scale)-1),int32_t(starty+(176*mapscreen_screenunit_scale)-1)))
8052 {
8053 int32_t cxstart=(x-startx)/(16*mapscreen_single_scale);
8054 int32_t cystart=(y-starty)/(16*mapscreen_single_scale);
8055 ComboPosition combo_start = {cxstart, cystart};
8056 if (pressframe)
8057 {
8058 last_pos = combo_start;
8059 }
8060 else if (combo_start == last_pos)
8061 {
8062 custom_vsync();
8063 refresh(rALL);
8064 continue;
8065 }
8066 else if(draw_mode == dm_auto)
8067 {
8068 // TODO: support when zoomed out.
8069 if (combo_autos[combo_auto_pos].getType() == AUTOCOMBO_FENCE || combo_autos[combo_auto_pos].getType() == AUTOCOMBO_Z4)
8070 {
8071 // Don't allow moving the brush at anything but cardinal directions while in these modes
8072 bool did_diag = std::abs(combo_start.x - last_pos.x) == 1 && std::abs(combo_start.y - last_pos.y) == 1;
8073
8074 if (did_diag)
8075 {
8076 int32_t oldx = last_pos.x;
8077 int32_t oldy = last_pos.y;
8078 int32_t cx = (oldx * 16 * mapscreen_single_scale) + 8;
8079 int32_t cy = (oldy * 16 * mapscreen_single_scale) + 8;
8080 int32_t nx = x - startxint;
8081 int32_t ny = y - startyint;
8082 if (std::abs(nx - cx) < std::abs(ny - cy))
8083 {
8084 oldy = vbound(oldy + ((ny - cy) < 0 ? -1 : 1), 0, 11);
8085 }
8086 else
8087 {
8088 oldx = vbound(oldx + ((nx - cx) < 0 ? -1 : 1), 0, 15);
8089 }
8090 combo_start = {oldx, oldy};
8091 }
8092 }
8093 }
8094 last_pos = combo_start;
8095
8096 switch(draw_mode)
8097 {
8098 case dm_normal:
8099 {
8100 int32_t cc=Combo;
8101
8102 for(int32_t cy=0; cy+cystart<num_combos_height&&cy<BrushHeight; cy++)
8103 {
8104 for(int32_t cx=0; cx+cxstart<num_combos_width&&cx<BrushWidth; cx++)
8105 {
8106 auto pos = combo_start + ComboPosition{cx, cy};
8107 cc=Combo + cx + cy*4;
8108 Map.DoSetComboCommand(pos, justcset ? -1 : cc, CSet);
8109 }
8110 }
8111
8112 update_combobrush();
8113 }
8114 break;
8115 case dm_cpool:
8116 {
8117 int32_t cid = Combo;
8118 int8_t cs = CSet;
8119 pool.pick(cid,cs);
8120 Map.DoSetComboCommand(combo_start, justcset ? -1 : cid, cs);
8121
8122 update_combobrush();
8123 }
8124 break;
8125
8126 case dm_alias:
8127 {
8128 combo_alias *combo = &combo_aliases[combo_apos];
8129 if(!combo->layermask)
8130 {
8131 int32_t ox=0, oy=0;
8132
8133 switch(alias_origin)
8134 {
8135 case 0:
8136 ox=0;
8137 oy=0;
8138 break;
8139
8140 case 1:
8141 ox=(combo->width);
8142 oy=0;
8143 break;
8144
8145 case 2:
8146 ox=0;
8147 oy=(combo->height);
8148 break;
8149
8150 case 3:
8151 ox=(combo->width);
8152 oy=(combo->height);
8153 break;
8154 }
8155
8156 for(int32_t cy=0; cy-oy+cystart<num_combos_height&&cy<=combo->height; cy++)
8157 {
8158 for(int32_t cx=0; cx-ox+cxstart<num_combos_width&&cx<=combo->width; cx++)
8159 {
8160 if((cx+cxstart-ox>=0)&&(cy+cystart-oy>=0))
8161 {
8162 int32_t p=(cy*(combo->width+1))+cx;
8163
8164 if(combo->combos[p])
8165 {
8166 auto pos = combo_start + ComboPosition{cx - ox, cy - oy};
8167 Map.DoSetComboCommand(pos, combo->combos[p], wrap(combo->csets[p]+alias_cset_mod, 0, 13));
8168 }
8169 }
8170 }
8171 }
8172 }
8173 else
8174 {
8175 int32_t laypos = 0;
8176 int32_t ox=0, oy=0;
8177
8178 switch(alias_origin)
8179 {
8180 case 0:
8181 ox=0;
8182 oy=0;
8183 break;
8184
8185 case 1:
8186 ox=(combo->width);
8187 oy=0;
8188 break;
8189
8190 case 2:
8191 ox=0;
8192 oy=(combo->height);
8193 break;
8194
8195 case 3:
8196 ox=(combo->width);
8197 oy=(combo->height);
8198 break;
8199 }
8200
8201 for(int32_t cz=0; cz<7; cz++)
8202 {
8203 if (cz > 0 && !(combo->layermask & (1<<(cz-1))))
8204 continue;
8205
8206 if (cz > 0)
8207 laypos++;
8208
8209 for(int32_t cy=0; cy-oy+cystart<num_combos_height&&cy<=combo->height; cy++)
8210 {
8211 for(int32_t cx=0; cx-ox+cxstart<num_combos_width&&cx<=combo->width; cx++)
8212 {
8213 if((cx+cxstart-ox>=0)&&(cy+cystart-oy>=0))
8214 {
8215 int32_t p=((cy*(combo->width+1))+cx)+((combo->width+1)*(combo->height+1)*laypos);
8216
8217 if (combo->combos[p])
8218 {
8219 auto pos = combo_start + ComboPosition{cx - ox, cy - oy};
8220 if(cz > 0 && Map.Scr(pos)->layermap[cz - 1] == 0)
8221 continue;
8222 int prev = CurrentLayer;
8223 CurrentLayer = cz;
8224 Map.DoSetComboCommand(pos, combo->combos[p], wrap(combo->csets[p]+alias_cset_mod, 0, 13));
8225 CurrentLayer = prev;
8226 }
8227 }
8228 }
8229 }
8230 }
8231 }
8232
8233 break;
8234 }
8235
8236 case dm_auto:
8237 {
8238 draw_autocombo(combo_start, gui_mouse_b() & 2, pressframe);
8239
8240 combobrushoverride = get_autocombo_floating_cid(combo_start, true);
8241 update_combobrush();
8242 }
8243 }
8244 }
8245 pressframe = false;
8246
8247 custom_vsync();
8248 refresh(rALL);
8249 }
8250
8251 Map.FinishListCommand();
8252 if(AutoBrushRevert)
8253 {
8254 AutoBrushRevert = false;
8255 BrushWidth = 1;
8256 BrushHeight = 1;
8257 }
8258 }
8259
8260 static void replace(ComboPosition start)
8261 {
8262 int32_t cid = Combo;
8263 int8_t cs = CSet;
8264 combo_pool const& pool = combo_pools[combo_pool_pos];
8265 if(draw_mode == dm_cpool && !pool.valid())
8266 return;
8267
8268 int c = start.truncate();
8269 mapscr* scr = Map.Scr(start, CurrentLayer);
8270 if (!scr) return;
8271
8272 int num_combos_width = 16 * Map.getViewSize();
8273 int num_combos_height = 11 * Map.getViewSize();
8274 int targetcombo = scr->data[c];
8275 int targetcset = scr->cset[c];
8276
8277 mark_save_dirty();
8278 Map.StartListCommand();
8279 if(key[KEY_LSHIFT] || key[KEY_RSHIFT])
8280 {
8281 for (int x = 0; x < num_combos_width; x++)
8282 {
8283 for (int y = 0; y < num_combos_height; y++)
8284 {
8285 ComboPosition pos = {x, y};
8286 int c = pos.truncate();
8287 mapscr* scr = Map.Scr(pos, CurrentLayer);
8288 if (!scr)
8289 continue;
8290
8291 if ((scr->cset[c]) == targetcset)
8292 {
8293 if(draw_mode == dm_cpool)
8294 pool.pick(cid,cs);
8295 Map.DoSetComboCommand(pos, -1, cs);
8296 }
8297 }
8298 }
8299 }
8300 else
8301 {
8302 for (int x = 0; x < num_combos_width; x++)
8303 {
8304 for (int y = 0; y < num_combos_height; y++)
8305 {
8306 ComboPosition pos = {x, y};
8307 int c = pos.truncate();
8308 mapscr* scr = Map.Scr(pos, CurrentLayer);
8309 if (!scr)
8310 continue;
8311
8312 if(((scr->data[c])==targetcombo) &&
8313 ((scr->cset[c])==targetcset))
8314 {
8315 if(draw_mode == dm_cpool)
8316 pool.pick(cid,cs);
8317 Map.DoSetComboCommand(pos, cid, cs);
8318 }
8319 }
8320 }
8321 }
8322 Map.FinishListCommand();
8323
8324 refresh(rMAP);
8325 }
8326
8327 static void draw_block(ComboPosition start, int32_t w, int32_t h)
8328 {
8329 int32_t cid = Combo;
8330 int8_t cs = CSet;
8331 if(draw_mode == dm_cpool)
8332 {
8333 combo_pool const& pool = combo_pools[combo_pool_pos];
8334 if(!pool.pick(cid,cs)) return;
8335 }
8336
8337 mapscr* scr = Map.Scr(start, CurrentLayer);
8338 if (!scr) return;
8339
8340 mark_save_dirty();
8341 Map.StartListCommand();
8342 for (int32_t y=0; y < h && y < 11*Map.getViewSize(); y++)
8343 for (int32_t x=0; x < w && x < 16*Map.getViewSize(); x++)
8344 {
8345 Map.DoSetComboCommand(start + ComboPosition{x, y}, cid+(y*4)+x, cs);
8346 }
8347
8348 Map.FinishListCommand();
8349 refresh(rMAP+rSCRMAP);
8350 }
8351
8352 static std::vector<ComboPosition> flood_filler(ComboPosition start_pos, bool allow_diagonal, std::function<bool(ComboPosition)> check)
8353 {
8354 std::vector<ComboPosition> seen, queue;
8355
8356 queue.push_back(start_pos);
8357 while (!queue.empty())
8358 {
8359 ComboPosition pos = queue.back();
8360 queue.pop_back();
8361 seen.push_back(pos);
8362
8363 ComboPosition pos2;
8364 #define FLOOD_FILLER_CHECK(dx, dy)\
8365 pos2 = pos + ComboPosition{dx, dy};\
8366 if (std::find(seen.begin(), seen.end(), pos2) == seen.end() && check(pos2))\
8367 queue.push_back(pos2);
8368
8369 FLOOD_FILLER_CHECK(0, 1);
8370 FLOOD_FILLER_CHECK(0, -1);
8371 FLOOD_FILLER_CHECK(1, 0);
8372 FLOOD_FILLER_CHECK(-1, 0);
8373
8374 if (allow_diagonal)
8375 {
8376 FLOOD_FILLER_CHECK(1, 1);
8377 FLOOD_FILLER_CHECK(1, -1);
8378 FLOOD_FILLER_CHECK(-1, 1);
8379 FLOOD_FILLER_CHECK(-1, -1);
8380 }
8381
8382 #undef FLOOD_FILLER_CHECK
8383 }
8384
8385 return seen;
8386 }
8387
8388 static void fill(int32_t targetcombo, int32_t targetcset, ComboPosition start_pos, bool allow_diagonal, bool only_cset)
8389 {
8390 bool rclick = gui_mouse_b() & 2;
8391 bool ignored_combo = false;
8392
8393 mapscr* scr = Map.ScrMakeValid(start_pos, CurrentLayer);
8394 if (!scr)
8395 return;
8396
8397 int num_combos_width = 16 * Map.getViewSize();
8398 int num_combos_height = 11 * Map.getViewSize();
8399
8400 auto combo_positions = flood_filler(start_pos, allow_diagonal, [&](ComboPosition pos){
8401 if (pos.x < 0 || pos.y < 0 || pos.x >= num_combos_width || pos.y >= num_combos_height)
8402 return false;
8403
8404 mapscr* scr = Map.Scr(pos, CurrentLayer);
8405 if (!scr || !scr->is_valid())
8406 return false;
8407
8408 int cid = scr->data[pos.truncate()];
8409 int cset = scr->cset[pos.truncate()];
8410
8411 if (draw_mode == dm_auto)
8412 {
8413 combo_auto const& cauto = combo_autos[combo_auto_pos];
8414
8415 ignored_combo = cauto.isIgnoredCombo(cid);
8416 if (rclick)
8417 {
8418 if (cauto.containsCombo(targetcombo))
8419 {
8420 if (!cauto.containsCombo(cid))
8421 return false;
8422 if (cauto.getType() == AUTOCOMBO_REPLACE && ignored_combo)
8423 return false;
8424 }
8425 else
8426 return false;
8427 }
8428 else
8429 {
8430 if (cid != targetcombo && !ignored_combo)
8431 return false;
8432 if (cauto.getType() == AUTOCOMBO_REPLACE && !ignored_combo)
8433 return false;
8434 }
8435
8436 if (cset != targetcset && !ignored_combo)
8437 return false;
8438 }
8439 else
8440 {
8441 if(!only_cset)
8442 {
8443 if (cid != targetcombo)
8444 return false;
8445 }
8446
8447 if (cset != targetcset)
8448 return false;
8449 }
8450
8451 return true;
8452 });
8453
8454 for (auto& pos : combo_positions)
8455 {
8456 int32_t cid = Combo;
8457 int8_t cs = CSet;
8458
8459 if (draw_mode == dm_cpool)
8460 {
8461 combo_pool const& pool = combo_pools[combo_pool_pos];
8462 if (!pool.pick(cid, cs)) continue;
8463 }
8464 else if (draw_mode == dm_auto)
8465 {
8466 combo_auto const& cauto = combo_autos[combo_auto_pos];
8467 if (!cauto.valid())
8468 continue;
8469 if (!rclick && (cauto.containsCombo(targetcombo) && !ignored_combo))
8470 continue;
8471 if (rclick && cauto.getEraseCombo() == targetcombo)
8472 continue;
8473 }
8474
8475 if (draw_mode == dm_auto)
8476 draw_autocombo(pos, rclick);
8477 else
8478 Map.DoSetComboCommand(pos, only_cset ? -1 : cid, cs);
8479 }
8480 }
8481
8482 static void fill_flag(int32_t targetflag, ComboPosition start_pos, bool allow_diagonal)
8483 {
8484 mapscr* scr = Map.ScrMakeValid(start_pos, CurrentLayer);
8485 if (!scr)
8486 return;
8487
8488 int num_combos_width = 16 * Map.getViewSize();
8489 int num_combos_height = 11 * Map.getViewSize();
8490
8491 auto combo_positions = flood_filler(start_pos, allow_diagonal, [&](ComboPosition pos){
8492 if (pos.x < 0 || pos.y < 0 || pos.x >= num_combos_width || pos.y >= num_combos_height)
8493 return false;
8494
8495 mapscr* scr = Map.Scr(pos, CurrentLayer);
8496 if (!scr || !scr->is_valid())
8497 return false;
8498
8499 if (scr->sflag[pos.truncate()] != targetflag)
8500 return false;
8501
8502 return true;
8503 });
8504
8505 for (auto& pos : combo_positions)
8506 Map.DoSetFlagCommand(pos, Flag);
8507 }
8508
8509 static void fill2(int32_t targetcombo, int32_t targetcset, ComboPosition pos, int32_t dir, int32_t diagonal, bool only_cset)
8510 {
8511 mapscr* scr = Map.Scr(pos, CurrentLayer);
8512 if (!scr || !scr->is_valid())
8513 return;
8514
8515 int cid = scr->data[pos.truncate()];
8516 int cset = scr->cset[pos.truncate()];
8517
8518 if (!only_cset)
8519 {
8520 if (cid == targetcombo)
8521 return;
8522 }
8523
8524 if (cset == targetcset)
8525 return;
8526
8527 cid = Combo;
8528 int8_t cs = CSet;
8529 if(draw_mode == dm_cpool)
8530 {
8531 combo_pool const& pool = combo_pools[combo_pool_pos];
8532 if(!pool.pick(cid,cs)) return;
8533 }
8534
8535 Map.DoSetComboCommand(pos, only_cset ? -1 : cid, cs);
8536
8537 int num_combos_width = 16 * Map.getViewSize();
8538 int num_combos_height = 11 * Map.getViewSize();
8539
8540 if (pos.y > 0 && dir != down)
8541 fill2(targetcombo, targetcset, pos + ComboPosition{0, -1}, up, diagonal, only_cset);
8542 if (pos.y < num_combos_height-1 && dir != up)
8543 fill2(targetcombo, targetcset, pos + ComboPosition{0, 1}, down, diagonal, only_cset);
8544 if (pos.x > 0 && dir != right)
8545 fill2(targetcombo, targetcset, pos + ComboPosition{-1, 0}, left, diagonal, only_cset);
8546 if (pos.x < num_combos_width-1 && dir != left)
8547 fill2(targetcombo, targetcset, pos + ComboPosition{1, 0}, right, diagonal, only_cset);
8548
8549 if (diagonal == 1)
8550 {
8551 if (pos.y > 0 && pos.x > 0 && dir != r_down)
8552 fill2(targetcombo, targetcset, pos + ComboPosition{-1, -1}, l_up, diagonal, only_cset);
8553 if (pos.y < num_combos_height-1 && pos.x < num_combos_width-1 && dir != l_up)
8554 fill2(targetcombo, targetcset, pos + ComboPosition{1, 1}, r_down, diagonal, only_cset);
8555 if (pos.x > 0 && pos.y < num_combos_height-1 && dir != r_up)
8556 fill2(targetcombo, targetcset, pos + ComboPosition{-1, 1}, l_down, diagonal, only_cset);
8557 if (pos.x < num_combos_width-1 && pos.y > 0 && dir != l_down)
8558 fill2(targetcombo, targetcset, pos + ComboPosition{1, -1}, r_up, diagonal, only_cset);
8559 }
8560 }
8561
8562
8563 enum SnapMode
8564 {
8565 SNAP_NONE, SNAP_HALF, SNAP_WHOLE
8566 };
8567 static void snap_xy(int& x, int& y, SnapMode mode, roundType rounding, optional<int> max_x = nullopt, optional<int> max_y = nullopt)
8568 {
8569 if(mode == SNAP_NONE)
8570 {
8571 if(max_x) x = vbound(x,*max_x,0);
8572 if(max_y) y = vbound(y,*max_y,0);
8573 return;
8574 }
8575 int xoff = 0, yoff = 0;
8576 switch(rounding)
8577 {
8578 case ROUND_TO_0:
8579 rounding = ROUND_DOWN;
8580 break;
8581 case ROUND_AWAY_0:
8582 rounding = ROUND_UP;
8583 break;
8584 }
8585 int r = 0;
8586 switch(mode)
8587 {
8588 case SNAP_HALF:
8589 r = 8;
8590 break;
8591 case SNAP_WHOLE:
8592 r = 16;
8593 break;
8594 }
8595 assert(r > 0);
8596 // r must be a power of 2, for bitwise reasons
8597 switch(rounding)
8598 {
8599 case ROUND_DOWN:
8600 break;
8601 case ROUND_UP:
8602 xoff = ((x & (r-1)) ? r : 0);
8603 yoff = ((y & (r-1)) ? r : 0);
8604 break;
8605 case ROUND_NEAREST:
8606 xoff = ((x & (r-1)) >= (r/2) ? r : 0);
8607 yoff = ((y & (r-1)) >= (r/2) ? r : 0);
8608 break;
8609 }
8610 x = (x & ~(r-1)) + xoff;
8611 y = (y & ~(r-1)) + yoff;
8612 if(max_x && x >= *max_x) x = *max_x-r;
8613 else if(max_x && x < 0) x = 0;
8614 if(max_y && y >= *max_y) y = *max_y-r;
8615 else if(max_y && y < 0) y = 0;
8616 }
8617
8618 static void doxypos(byte &px2, byte &py2, int32_t color, SnapMode snap_mode,
8619 SnapMode shift_mode, bool immediately, int32_t cursoroffx,
8620 int32_t cursoroffy, int32_t iconw, int32_t iconh)
8621 {
8622 int32_t tempcb=ComboBrush;
8623 ComboBrush=0;
8624 MouseSprite::set(ZQM_POINT_BOX);
8625
8626 int viz_off_x = (active_visible_screen ? active_visible_screen->dx * 256 : 0);
8627 int viz_off_y = (active_visible_screen ? active_visible_screen->dy * 176 : 0);
8628
8629 int32_t oldpx=px2, oldpy=py2;
8630 int32_t startxint=mapscreen_x+(showedges?int32_t(16*mapscreen_single_scale):0);
8631 int32_t startyint=mapscreen_y+(showedges?int32_t(16*mapscreen_single_scale):0);
8632 showxypos_x=px2 + viz_off_x;
8633 showxypos_y=py2 + viz_off_y;
8634 showxypos_w=iconw;
8635 showxypos_h=iconh;
8636 showxypos_color=vc(color);
8637 showxypos_icon=!showxypos_dummy;
8638 bool canedit=false;
8639 bool done=false;
8640
8641 clear_tooltip();
8642
8643 while(!done && (!(gui_mouse_b()&2) || immediately))
8644 {
8645 if(!gui_mouse_b() || immediately)
8646 {
8647 canedit=true;
8648 }
8649
8650 // TODO: would be nice if these bounds were based on the individual screen.
8651 if(canedit && gui_mouse_b()==1 && isinRect(gui_mouse_x(),gui_mouse_y(),startxint,startyint,(startxint+(256*mapscreen_screenunit_scale)-1),(startyint+(176*mapscreen_screenunit_scale)-1)))
8652 {
8653 set_mouse_range(startxint,startyint,int32_t(startxint+(256*mapscreen_screenunit_scale)-1),int32_t(startyint+(176*mapscreen_screenunit_scale)-1));
8654
8655 double offx = 0, offy = 0;
8656 roundType rounding = ROUND_DOWN;
8657 if(DragCenterOfSquares)
8658 {
8659 offx -= iconw*mapscreen_single_scale/2;
8660 offy -= iconh*mapscreen_single_scale/2;
8661 rounding = ROUND_NEAREST;
8662 }
8663 int32_t x, y;
8664 do
8665 {
8666 poll_keyboard(); // re-check shift key!
8667 x=int32_t((gui_mouse_x()-startxint+offx)/mapscreen_single_scale)-cursoroffx;
8668 y=int32_t((gui_mouse_y()-startyint+offy)/mapscreen_single_scale)-cursoroffy;
8669 showxypos_cursor_icon=true;
8670 showxypos_cursor_color = showxypos_color;
8671 auto _mode = (key[KEY_LSHIFT] || key[KEY_RSHIFT]) ? shift_mode : snap_mode;
8672 showxypos_cursor_x = x-viz_off_x;
8673 showxypos_cursor_y = y-viz_off_y;
8674 snap_xy(showxypos_cursor_x, showxypos_cursor_y, _mode, rounding, 256, 176);
8675 showxypos_cursor_x += viz_off_x;
8676 showxypos_cursor_y += viz_off_y;
8677 custom_vsync();
8678 refresh(rALL | rNOCURSOR);
8679 int32_t xpos[2], ypos[2];
8680 int32_t x1,y1,x2,y2;
8681
8682 char b1[200] = {0};
8683 char b2[200] = {0};
8684 if(showxypos_dummy)
8685 strcpy(b1, "DUMMY MEASURING");
8686 else sprintf(b1, "%d %d",oldpx,oldpy);
8687 sprintf(b2, "%d %d (%d %d)",x-viz_off_x,y-viz_off_y,showxypos_cursor_x-viz_off_x,showxypos_cursor_y-viz_off_y);
8688
8689 int len[2] = {text_length(font,b1),text_length(font,b2)};
8690
8691 if(is_compact)
8692 {
8693 xpos[0] = 4;
8694 ypos[0] = layer_panel.y - 21;
8695 xpos[1] = xpos[0];
8696 ypos[1] = ypos[0]+10;
8697 }
8698 else
8699 {
8700 xpos[0] = 450;
8701 ypos[0] = 405;
8702 xpos[1] = xpos[0];
8703 ypos[1] = ypos[0]+10;
8704 }
8705
8706 x1 = xpos[0];
8707 y1 = ypos[0];
8708 x2 = xpos[0];
8709 y2 = ypos[0];
8710 for(auto q = 0; q < 2; ++q)
8711 {
8712 if(xpos[q] < x1)
8713 x1 = xpos[q];
8714 if(ypos[q] < y1)
8715 y1 = ypos[q];
8716 if(ypos[q] > y2)
8717 y2 = ypos[q];
8718 if(xpos[q] + len[q] > x2)
8719 x2 = xpos[q] + len[q];
8720 }
8721 x1 -= 4;
8722 y1 -= 2;
8723 y2 += text_height(font)+2;
8724
8725 auto minx = zc_min(xpos[0],xpos[1]);
8726 auto miny = zc_min(ypos[0],ypos[1]);
8727 rectfill(screen,x1,y1,x2,y2,vc(0));
8728 textprintf_ex(screen,font,xpos[0],ypos[0],vc(15),vc(0),"%s",b1);
8729 textprintf_ex(screen,font,xpos[1],ypos[1],vc(15),vc(0),"%s",b2);
8730 update_hw_screen();
8731 }
8732 while(gui_mouse_b()==1);
8733
8734 if(gui_mouse_b()==0)
8735 {
8736 auto _mode = (key[KEY_LSHIFT] || key[KEY_RSHIFT]) ? shift_mode : snap_mode;
8737 int x2 = vbound(x-viz_off_x,0,255);
8738 int y2 = vbound(y-viz_off_y,0,175);
8739 snap_xy(x2, y2, _mode, rounding, 256, 176);
8740 px2=byte(x2);
8741 py2=byte(y2);
8742 }
8743
8744 set_mouse_range(0,0,zq_screen_w-1,zq_screen_h-1);
8745 done=true;
8746 }
8747
8748 if(keypressed())
8749 {
8750 switch(readkey()>>8)
8751 {
8752 case KEY_ESC:
8753 case KEY_ENTER:
8754 goto finished;
8755 }
8756 }
8757
8758 custom_vsync();
8759 refresh(rALL | rNOCURSOR);
8760 }
8761
8762 finished:
8763 MouseSprite::set(ZQM_NORMAL);
8764 refresh(rMAP+rMENU);
8765
8766 while(gui_mouse_b())
8767 {
8768 /* do nothing */
8769 rest(1);
8770 }
8771
8772 showxypos_x=-1000;
8773 showxypos_y=-1000;
8774 showxypos_color=-1000;
8775 showxypos_ffc=-1000;
8776 showxypos_icon=false;
8777 showxypos_cursor_x=-1000;
8778 showxypos_cursor_y=-1000;
8779 showxypos_cursor_icon=false;
8780 showxypos_cursor_color=-1000;
8781 showxypos_dummy=false;
8782
8783 if(px2!=oldpx||py2!=oldpy)
8784 {
8785 mark_save_dirty();
8786 }
8787
8788 ComboBrush=tempcb;
8789 }
8790 static void doxypos(byte &px2,byte &py2,int32_t color,SnapMode snap_mode, optional<SnapMode> shift_mode = nullopt)
8791 {
8792 doxypos(px2,py2,color,snap_mode,shift_mode ? *shift_mode : snap_mode,false,0,0,16,16);
8793 }
8794
8795 bool placing_flags = false;
8796 void doflags()
8797 {
8798 placing_flags = true;
8799 int of=Flags;
8800 Flags=cFLAGS;
8801 refresh(rMAP | rNOCURSOR);
8802
8803 bool canedit=false;
8804 bool didShift = false;
8805 int tFlag = Flag;
8806 while(!(gui_mouse_b()&2) && !handle_close_btn_quit())
8807 {
8808 int x=gui_mouse_x();
8809 int y=gui_mouse_y();
8810 double startx=mapscreen_x+(showedges?(16*mapscreen_single_scale):0);
8811 double starty=mapscreen_y+(showedges?(16*mapscreen_single_scale):0);
8812 int startxint=mapscreen_x+(showedges?int(16*mapscreen_single_scale):0);
8813 int startyint=mapscreen_y+(showedges?int(16*mapscreen_single_scale):0);
8814 int cx=(x-startxint)/int(16*mapscreen_single_scale);
8815 int cy=(y-startyint)/int(16*mapscreen_single_scale);
8816 ComboPosition combo_pos = {cx, cy};
8817 int c = combo_pos.truncate();
8818
8819 if(!gui_mouse_b())
8820 canedit=true;
8821 bool shift = key[KEY_LSHIFT] || key[KEY_RSHIFT];
8822
8823 if(canedit && gui_mouse_b()==1 && isinRect(x,y,startxint,startyint,int(startx+(256*mapscreen_screenunit_scale)-1),int(starty+(176*mapscreen_screenunit_scale)-1)))
8824 {
8825 mapscr* cur_scr = Map.Scr(combo_pos, CurrentLayer);
8826 if (!cur_scr) continue;
8827
8828 Map.setCurrScr(Map.getScreenForPosition(combo_pos));
8829
8830 if(key[KEY_ALT]||key[KEY_ALTGR])
8831 Flag = cur_scr->sflag[c];
8832 else
8833 {
8834 mark_save_dirty();
8835 int tflag = Flag;
8836 if(shift)
8837 Flag = mfNONE;
8838 if(CurrentLayer!=0)
8839 {
8840 // Notify if they are using a flag that doesn't work on this layer.
8841 if(!skipLayerWarning && ((Flag >= mfTRAP_H && Flag < mfPUSHD) || (Flag == mfFAIRY) || (Flag == mfMAGICFAIRY)
8842 || (Flag == mfALLFAIRY) || (Flag == mfRAFT) || (Flag == mfRAFT_BRANCH)
8843 || (Flag == mfDIVE_ITEM) || (Flag == mfARMOS_SECRET) || (Flag == mfNOENEMY)
8844 || (Flag == mfZELDA)))
8845 {
8846 InfoDialog("Notice","You are currently working on layer "
8847 +to_string(CurrentLayer)
8848 +". This combo flag does not function on layers above '0'.").show();
8849 }
8850 if(!skipLayerWarning && CurrentLayer > 2 &&
8851 ((Flag == mfBLOCKHOLE) || (Flag >= mfPUSHD && Flag < mfNOBLOCKS)
8852 || (Flag == mfPUSHUD) || (Flag == mfPUSH4)))
8853 {
8854 InfoDialog("Notice","You are currently working on layer "
8855 +to_string(CurrentLayer)
8856 +". This combo flag does not function on layers above '2'.").show();
8857 }
8858 }
8859 if(CHECK_CTRL_CMD)
8860 {
8861 switch(fill_type)
8862 {
8863 case 0:
8864 flood_flag();
8865 break;
8866
8867 case 1:
8868 case 3:
8869 fill_4_flag();
8870 break;
8871
8872 case 2:
8873 case 4:
8874 fill_8_flag();
8875 break;
8876 }
8877 }
8878 else
8879 {
8880 Map.DoSetFlagCommand(combo_pos, Flag);
8881 }
8882 Flag = tflag;
8883 }
8884 }
8885
8886 if(mouse_z)
8887 {
8888 for(int i=0; i<abs(mouse_z); ++i)
8889 {
8890 if(mouse_z>0)
8891 onIncreaseFlag();
8892 else
8893 onDecreaseFlag();
8894 }
8895
8896 position_mouse_z(0);
8897 }
8898
8899 if(keypressed())
8900 {
8901 int k = readkey();
8902 switch(k>>8)
8903 {
8904 case KEY_ESC:
8905 case KEY_ENTER:
8906 goto finished;
8907 }
8908 object_message(dialogs+1, MSG_XCHAR, k);
8909 Flags=cFLAGS;
8910 }
8911
8912 MouseSprite::set(ZQM_FLAG_0+(shift?0:Flag%16));
8913
8914 refresh(rALL | rCLEAR | rNOCURSOR);
8915 custom_vsync();
8916 }
8917
8918 finished:
8919 Flags=of;
8920 placing_flags = false;
8921 MouseSprite::set(ZQM_NORMAL);
8922 refresh(rMAP+rMENU);
8923
8924 while(gui_mouse_b())
8925 {
8926 /* do nothing */
8927 rest(1);
8928 }
8929 }
8930
8931 // Drag FFCs around
8932 static void moveffc(int i, int cx, int cy)
8933 {
8934 mapscr* scr = active_visible_screen->scr;
8935 int screen = active_visible_screen->screen;
8936
8937 int32_t ffx = vbound(scr->ffcs[i].x.getFloor(),0,240);
8938 int32_t ffy = vbound(scr->ffcs[i].y.getFloor(),0,160);
8939 int32_t offx = ffx, offy = ffy;
8940 showxypos_ffc = i;
8941 doxypos((byte&)ffx,(byte&)ffy,15,SNAP_HALF,SNAP_NONE,true,0,0,(scr->ffTileWidth(i)*16),(scr->ffTileHeight(i)*16));
8942 if(ffx > 240) ffx = 240;
8943 if(ffy > 160) ffy = 160;
8944 if((ffx != offx) || (ffy != offy))
8945 {
8946 auto set_ffc_data = set_ffc_command::create_data(scr->ffcs[i]);
8947 set_ffc_data.x = ffx;
8948 set_ffc_data.y = ffy;
8949 Map.DoSetFFCCommand(Map.getCurrMap(), screen, i, set_ffc_data);
8950 mark_save_dirty();
8951 }
8952 }
8953
8954 void set_brush_width(int32_t width);
8955 void set_brush_height(int32_t height);
8956
8957 int32_t set_brush_width_1()
8958 {
8959 set_brush_width(1);
8960 return D_O_K;
8961 }
8962 int32_t set_brush_width_2()
8963 {
8964 set_brush_width(2);
8965 return D_O_K;
8966 }
8967 int32_t set_brush_width_3()
8968 {
8969 set_brush_width(3);
8970 return D_O_K;
8971 }
8972 int32_t set_brush_width_4()
8973 {
8974 set_brush_width(4);
8975 return D_O_K;
8976 }
8977 int32_t set_brush_width_5()
8978 {
8979 set_brush_width(5);
8980 return D_O_K;
8981 }
8982 int32_t set_brush_width_6()
8983 {
8984 set_brush_width(6);
8985 return D_O_K;
8986 }
8987 int32_t set_brush_width_7()
8988 {
8989 set_brush_width(7);
8990 return D_O_K;
8991 }
8992 int32_t set_brush_width_8()
8993 {
8994 set_brush_width(8);
8995 return D_O_K;
8996 }
8997 int32_t set_brush_width_9()
8998 {
8999 set_brush_width(9);
9000 return D_O_K;
9001 }
9002 int32_t set_brush_width_10()
9003 {
9004 set_brush_width(10);
9005 return D_O_K;
9006 }
9007 int32_t set_brush_width_11()
9008 {
9009 set_brush_width(11);
9010 return D_O_K;
9011 }
9012 int32_t set_brush_width_12()
9013 {
9014 set_brush_width(12);
9015 return D_O_K;
9016 }
9017 int32_t set_brush_width_13()
9018 {
9019 set_brush_width(13);
9020 return D_O_K;
9021 }
9022 int32_t set_brush_width_14()
9023 {
9024 set_brush_width(14);
9025 return D_O_K;
9026 }
9027 int32_t set_brush_width_15()
9028 {
9029 set_brush_width(15);
9030 return D_O_K;
9031 }
9032 int32_t set_brush_width_16()
9033 {
9034 set_brush_width(16);
9035 return D_O_K;
9036 }
9037
9038 int32_t set_brush_height_1()
9039 {
9040 set_brush_height(1);
9041 return D_O_K;
9042 }
9043 int32_t set_brush_height_2()
9044 {
9045 set_brush_height(2);
9046 return D_O_K;
9047 }
9048 int32_t set_brush_height_3()
9049 {
9050 set_brush_height(3);
9051 return D_O_K;
9052 }
9053 int32_t set_brush_height_4()
9054 {
9055 set_brush_height(4);
9056 return D_O_K;
9057 }
9058 int32_t set_brush_height_5()
9059 {
9060 set_brush_height(5);
9061 return D_O_K;
9062 }
9063 int32_t set_brush_height_6()
9064 {
9065 set_brush_height(6);
9066 return D_O_K;
9067 }
9068 int32_t set_brush_height_7()
9069 {
9070 set_brush_height(7);
9071 return D_O_K;
9072 }
9073 int32_t set_brush_height_8()
9074 {
9075 set_brush_height(8);
9076 return D_O_K;
9077 }
9078 int32_t set_brush_height_9()
9079 {
9080 set_brush_height(9);
9081 return D_O_K;
9082 }
9083 int32_t set_brush_height_10()
9084 {
9085 set_brush_height(10);
9086 return D_O_K;
9087 }
9088 int32_t set_brush_height_11()
9089 {
9090 set_brush_height(11);
9091 return D_O_K;
9092 }
9093
9094
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu brush_width_menu
9095 204 {
9096
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "1", set_brush_width_1 },
9097
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2", set_brush_width_2 },
9098
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "3", set_brush_width_3 },
9099
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "4", set_brush_width_4 },
9100
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "5", set_brush_width_5 },
9101
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "6", set_brush_width_6 },
9102
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "7", set_brush_width_7 },
9103
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "8", set_brush_width_8 },
9104
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "9", set_brush_width_9 },
9105
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "10", set_brush_width_10 },
9106
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "11", set_brush_width_11 },
9107
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "12", set_brush_width_12 },
9108
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "13", set_brush_width_13 },
9109
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "14", set_brush_width_14 },
9110
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "15", set_brush_width_15 },
9111
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "16", set_brush_width_16 },
9112 };
9113
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu brush_height_menu
9114 144 {
9115
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "1", set_brush_height_1 },
9116
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2", set_brush_height_2 },
9117
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "3", set_brush_height_3 },
9118
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "4", set_brush_height_4 },
9119
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "5", set_brush_height_5 },
9120
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "6", set_brush_height_6 },
9121
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "7", set_brush_height_7 },
9122
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "8", set_brush_height_8 },
9123
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "9", set_brush_height_9 },
9124
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "10", set_brush_height_10 },
9125
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "11", set_brush_height_11 },
9126 };
9127
9128 int toggle_autobrush();
9129 int toggle_combobrush();
9130 int toggle_floatbrush();
9131 enum
9132 {
9133 MENUID_BRUSH_AUTOBRUSH,
9134 MENUID_BRUSH_WIDTH,
9135 MENUID_BRUSH_HEIGHT,
9136 MENUID_BRUSH_COMBOBRUSH,
9137 MENUID_BRUSH_FLOATBRUSH,
9138 };
9139
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu brush_menu
9140 72 {
9141
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "AutoBrush", toggle_autobrush, MENUID_BRUSH_AUTOBRUSH },
9142
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Brush Width ", &brush_width_menu, MENUID_BRUSH_WIDTH },
9143
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Brush Height ", &brush_height_menu, MENUID_BRUSH_HEIGHT },
9144
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "ComboBrush", toggle_combobrush, MENUID_BRUSH_COMBOBRUSH },
9145
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "FloatBrush", toggle_floatbrush, MENUID_BRUSH_FLOATBRUSH },
9146 };
9147 int toggle_autobrush()
9148 {
9149 AutoBrush = AutoBrush ? 0 : 1;
9150 BrushWidth = BrushHeight = 1;
9151 brush_menu.select_uid(MENUID_BRUSH_AUTOBRUSH, AutoBrush);
9152 brush_menu.disable_uid(MENUID_BRUSH_WIDTH, AutoBrush);
9153 brush_menu.disable_uid(MENUID_BRUSH_HEIGHT, AutoBrush);
9154 zc_set_config("zquest","autobrush",AutoBrush);
9155 return D_O_K;
9156 }
9157 int toggle_combobrush()
9158 {
9159 ComboBrush = ComboBrush ? 0 : 1;
9160 brush_menu.select_uid(MENUID_BRUSH_COMBOBRUSH, ComboBrush);
9161 zc_set_config("zquest","combo_brush",ComboBrush);
9162 return D_O_K;
9163 }
9164 int toggle_floatbrush()
9165 {
9166 FloatBrush = FloatBrush ? 0 : 1;
9167 brush_menu.select_uid(MENUID_BRUSH_FLOATBRUSH, FloatBrush);
9168 zc_set_config("zquest","float_brush",FloatBrush);
9169 return D_O_K;
9170 }
9171
9172 int32_t set_flood();
9173 int32_t set_fill_4();
9174 int32_t set_fill_8();
9175 int32_t set_fill2_4();
9176 int32_t set_fill2_8();
9177
9178 // Sets every combo.
9179 void flood()
9180 {
9181 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9182 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9183 if (!scr || !scr->is_valid())
9184 return;
9185
9186 mark_save_dirty();
9187
9188 bool include_combos = !(key[KEY_LSHIFT]||key[KEY_RSHIFT]);
9189
9190 int num_combos_width = 16 * Map.getViewSize();
9191 int num_combos_height = 11 * Map.getViewSize();
9192
9193 Map.StartListCommand();
9194 for (int x = 0; x < num_combos_width; x++)
9195 {
9196 for (int y = 0; y < num_combos_height; y++)
9197 {
9198 ComboPosition pos = {x, y};
9199 mapscr* scr = Map.Scr(pos, CurrentLayer);
9200 if (!scr || !scr->is_valid())
9201 continue;
9202
9203 if (draw_mode == dm_auto)
9204 draw_autocombo(pos, gui_mouse_b() & 2);
9205 else
9206 Map.DoSetComboCommand(pos, include_combos ? Combo : -1, CSet);
9207 }
9208 }
9209 Map.FinishListCommand();
9210
9211 refresh(rMAP+rSCRMAP);
9212 }
9213 void flood_flag()
9214 {
9215 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9216 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9217 if (!scr || !scr->is_valid())
9218 return;
9219
9220 mark_save_dirty();
9221
9222 int num_combos_width = 16 * Map.getViewSize();
9223 int num_combos_height = 11 * Map.getViewSize();
9224
9225 Map.StartListCommand();
9226 for (int x = 0; x < num_combos_width; x++)
9227 {
9228 for (int y = 0; y < num_combos_height; y++)
9229 {
9230 ComboPosition pos = {x, y};
9231 mapscr* scr = Map.Scr(pos, CurrentLayer);
9232 if (!scr || !scr->is_valid())
9233 continue;
9234
9235 Map.DoSetFlagCommand(pos, Flag);
9236 }
9237 }
9238 Map.FinishListCommand();
9239
9240 refresh(rMAP+rSCRMAP);
9241 }
9242
9243 void fill_4()
9244 {
9245 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9246 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9247 if (!scr)
9248 return;
9249
9250 int c = pos.truncate();
9251 if (draw_mode == dm_cpool || draw_mode == dm_auto
9252 || (scr->cset[c]!=CSet || (scr->data[c]!=Combo && !(key[KEY_LSHIFT]||key[KEY_RSHIFT]))))
9253 {
9254 mark_save_dirty();
9255
9256 Map.StartListCommand();
9257 if (draw_mode == dm_auto && (combo_autos[combo_auto_pos].getType() == AUTOCOMBO_FENCE ||
9258 combo_autos[combo_auto_pos].getType() == AUTOCOMBO_Z4))
9259 {
9260 draw_autocombo_command(pos);
9261 }
9262 else
9263 {
9264 bool allow_diagonal = false;
9265 fill(scr->data[c], scr->cset[c], pos, allow_diagonal, (key[KEY_LSHIFT] || key[KEY_RSHIFT]));
9266 }
9267 Map.FinishListCommand();
9268 refresh(rMAP+rSCRMAP);
9269 }
9270 }
9271 void fill_4_flag()
9272 {
9273 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9274 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9275 if (!scr)
9276 return;
9277
9278 int flag = scr->sflag[pos.truncate()];
9279 if (flag != Flag)
9280 {
9281 mark_save_dirty();
9282
9283 Map.StartListCommand();
9284 bool allow_diagonal = false;
9285 fill_flag(flag, pos, allow_diagonal);
9286 Map.FinishListCommand();
9287 refresh(rMAP+rSCRMAP);
9288 }
9289 }
9290 void fill_8()
9291 {
9292 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9293 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9294 if (!scr)
9295 return;
9296
9297 int c = pos.truncate();
9298 if (draw_mode == dm_cpool || draw_mode == dm_auto
9299 || (scr->cset[c] != CSet ||
9300 (scr->data[c] != Combo &&
9301 !(key[KEY_LSHIFT]||key[KEY_RSHIFT]))))
9302 {
9303 mark_save_dirty();
9304
9305 Map.StartListCommand();
9306 bool allow_diagonal = true;
9307 fill(scr->data[c], scr->cset[c], pos, allow_diagonal, (key[KEY_LSHIFT]||key[KEY_RSHIFT]));
9308 Map.FinishListCommand();
9309
9310 refresh(rMAP+rSCRMAP);
9311 }
9312 }
9313 void fill_8_flag()
9314 {
9315 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9316 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9317 if (!scr)
9318 return;
9319
9320 int flag = scr->sflag[pos.truncate()];
9321 if (flag != Flag)
9322 {
9323 mark_save_dirty();
9324
9325 Map.StartListCommand();
9326 bool allow_diagonal = true;
9327 fill_flag(flag, pos, allow_diagonal);
9328 Map.FinishListCommand();
9329 refresh(rMAP+rSCRMAP);
9330 }
9331 }
9332
9333 void fill2_4()
9334 {
9335 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9336 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9337 if (!scr)
9338 return;
9339
9340 mark_save_dirty();
9341
9342 Map.StartListCommand();
9343 fill2(Combo, CSet, pos, 255, 0, (key[KEY_LSHIFT]||key[KEY_RSHIFT]));
9344 Map.FinishListCommand();
9345 refresh(rMAP+rSCRMAP);
9346 }
9347
9348 void fill2_8()
9349 {
9350 ComboPosition pos = get_mapscreen_mouse_combo_pos();
9351 mapscr* scr = Map.ScrMakeValid(pos, CurrentLayer);
9352 if (!scr)
9353 return;
9354
9355 mark_save_dirty();
9356
9357 Map.StartListCommand();
9358 fill2(Combo, CSet, pos, 255, 1, (key[KEY_LSHIFT]||key[KEY_RSHIFT]));
9359 Map.FinishListCommand();
9360
9361 refresh(rMAP+rSCRMAP);
9362 }
9363
9364
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu fill_menu
9365 72 {
9366
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Flood", set_flood, 0 },
9367
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fill (4-way)", set_fill_4, 1 },
9368
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fill (8-way)", set_fill_8, 2 },
9369
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fill2 (4-way)", set_fill2_4, 3 },
9370
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Fill2 (8-way)", set_fill2_8, 4 },
9371 };
9372 void set_filltype(int ty)
9373 {
9374 fill_type = ty;
9375 fill_menu.select_only_uid(ty);
9376 }
9377
9378 int32_t set_flood()
9379 {
9380 set_filltype(0);
9381 return D_O_K;
9382 }
9383
9384 int32_t set_fill_4()
9385 {
9386 set_filltype(1);
9387 return D_O_K;
9388 }
9389
9390 int32_t set_fill_8()
9391 {
9392 set_filltype(2);
9393 return D_O_K;
9394 }
9395
9396 int32_t set_fill2_4()
9397 {
9398 set_filltype(3);
9399 return D_O_K;
9400 }
9401
9402 int32_t set_fill2_8()
9403 {
9404 set_filltype(4);
9405 return D_O_K;
9406 }
9407
9408 int32_t draw_block_1_2()
9409 {
9410 draw_block(mouse_combo_pos,1,2);
9411 return D_O_K;
9412 }
9413
9414 int32_t draw_block_2_1()
9415 {
9416 draw_block(mouse_combo_pos,2,1);
9417 return D_O_K;
9418 }
9419
9420 int32_t draw_block_2_2()
9421 {
9422 draw_block(mouse_combo_pos,2,2);
9423 return D_O_K;
9424 }
9425
9426 int32_t draw_block_2_3()
9427 {
9428 draw_block(mouse_combo_pos,2,3);
9429 return D_O_K;
9430 }
9431
9432 int32_t draw_block_3_2()
9433 {
9434 draw_block(mouse_combo_pos,3,2);
9435 return D_O_K;
9436 }
9437
9438 int32_t draw_block_3_3()
9439 {
9440 draw_block(mouse_combo_pos,3,3);
9441 return D_O_K;
9442 }
9443
9444 int32_t draw_block_4_2()
9445 {
9446 draw_block(mouse_combo_pos,4,2);
9447 return D_O_K;
9448 }
9449
9450 int32_t draw_block_4_4()
9451 {
9452 draw_block(mouse_combo_pos,4,4);
9453 return D_O_K;
9454 }
9455
9456
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu draw_block_menu
9457 108 {
9458
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "1x2", draw_block_1_2 },
9459
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2x1", draw_block_2_1 },
9460
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2x2", draw_block_2_2 },
9461
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "2x3", draw_block_2_3 },
9462
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "3x2", draw_block_3_2 },
9463
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "3x3", draw_block_3_3 },
9464
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "4x2", draw_block_4_2 },
9465
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "4x4", draw_block_4_4 },
9466 };
9467
9468
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu paste_screen_menu
9469 60 {
9470
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste", onPaste },
9471
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste All", onPasteAll },
9472
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste to All", onPasteToAll },
9473
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste All to All", onPasteAllToAll },
9474 };
9475
9476 int32_t scrollto_cmb(int32_t cid)
9477 {
9478 auto& sqr = combolist[current_combolist];
9479 int32_t res = vbound(cid-(sqr.w*sqr.h/2),0,MAXCOMBOS-(sqr.w*sqr.h));
9480 res -= res%sqr.w;
9481 return res;
9482 }
9483 int32_t scrollto_alias(int32_t alid)
9484 {
9485 auto& sqr = comboaliaslist[current_comboalist];
9486 int32_t res = vbound(alid-(sqr.w*sqr.h/2),0,MAXCOMBOALIASES-(sqr.w*sqr.h));
9487 res -= res%sqr.w;
9488 return res;
9489 }
9490
9491 int32_t scrollto_cpool(int32_t cpid)
9492 {
9493 auto& sqr = comboaliaslist[current_cpoollist];
9494 int32_t res = vbound(cpid-(sqr.w*sqr.h/2),0,MAXCOMBOPOOLS-(sqr.w*sqr.h));
9495 res -= res%sqr.w;
9496 return res;
9497 }
9498
9499 int32_t scrollto_cauto(int32_t caid)
9500 {
9501 auto& sqr = comboaliaslist[current_cautolist];
9502 int32_t res = vbound(caid - (sqr.w * sqr.h / 2), 0, MAXCOMBOPOOLS - (sqr.w * sqr.h));
9503 res -= res % sqr.w;
9504 return res;
9505 }
9506
9507 void add_favorite_combo_block(int32_t favind, int32_t cid, bool force)
9508 {
9509 int32_t w = vbound(BrushWidth, 1, 4);
9510 int32_t h = vbound(BrushHeight, 1, 7);
9511 for (int32_t xi = 0; xi < w; ++xi)
9512 {
9513 for (int32_t yi = 0; yi < h; ++yi)
9514 {
9515 int32_t cx = cid % 4;
9516 int32_t cy = cid / 4;
9517 int32_t cc = (cy + yi) * 4 + cx + xi;
9518 int32_t fx = favind % FAVORITECOMBO_PER_ROW;
9519 int32_t fy = favind / FAVORITECOMBO_PER_ROW;
9520 int32_t fc = (fy + yi) * FAVORITECOMBO_PER_ROW + fx + xi + FAVORITECOMBO_PER_PAGE * FavoriteComboPage;
9521
9522 if (cx + xi < 4 && cc < MAXCOMBOS && fx + xi < FAVORITECOMBO_PER_ROW && fy + yi < FAVORITECOMBO_PER_COLUMN)
9523 {
9524 if (favorite_combos[fc] < 0 || force)
9525 {
9526 favorite_combo_modes[fc] = dm_normal;
9527 favorite_combos[fc] = cc;
9528 }
9529 }
9530 }
9531 }
9532 }
9533
9534 void onRCSelectCombo(int32_t c)
9535 {
9536 int32_t drawmap, drawscr;
9537
9538 if(CurrentLayer==0)
9539 {
9540 drawmap=Map.getCurrMap();
9541 drawscr=Map.getCurrScr();
9542 }
9543 else
9544 {
9545 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
9546 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
9547 }
9548 mapscr* draw_mapscr = Map.AbsoluteScr(drawmap, drawscr);
9549 if(!draw_mapscr) return;
9550
9551 Combo=draw_mapscr->data[c];
9552 if(AutoBrush)
9553 BrushWidth = BrushHeight = 1;
9554 }
9555
9556 void onRCScrollToombo(int32_t c)
9557 {
9558 int32_t drawmap, drawscr;
9559
9560 if(CurrentLayer==0)
9561 {
9562 drawmap=Map.getCurrMap();
9563 drawscr=Map.getCurrScr();
9564 }
9565 else
9566 {
9567 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
9568 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
9569 }
9570 mapscr* draw_mapscr = Map.AbsoluteScr(drawmap, drawscr);
9571 if(!draw_mapscr) return;
9572
9573 auto& sqr = combolist[current_combolist];
9574 First[current_combolist]=scrollto_cmb(draw_mapscr->data[c]);
9575 }
9576
9577 enum
9578 {
9579 MENUID_RCSCREEN_PASTE,
9580 MENUID_RCSCREEN_ADVPASTE,
9581 MENUID_RCSCREEN_SPECPASTE,
9582 };
9583
1/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 static NewMenu rc_menu_screen
9584 60 {
9585
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Copy Screen", onCopy },
9586
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "Paste Screen", &paste_screen_menu, MENUID_RCSCREEN_PASTE },
9587
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "...Advanced Paste", &paste_menu, MENUID_RCSCREEN_ADVPASTE },
9588
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 { "...Special Paste", &paste_item_menu, MENUID_RCSCREEN_SPECPASTE },
9589 };
9590
9591 void call_options_dlg();
9592 int32_t onOptions()
9593 {
9594 call_options_dlg();
9595 brush_menu.select_uid(MENUID_BRUSH_AUTOBRUSH, AutoBrush);
9596 brush_menu.disable_uid(MENUID_BRUSH_WIDTH, AutoBrush);
9597 brush_menu.disable_uid(MENUID_BRUSH_HEIGHT, AutoBrush);
9598 brush_menu.select_uid(MENUID_BRUSH_FLOATBRUSH, FloatBrush);
9599 brush_menu.select_uid(MENUID_BRUSH_COMBOBRUSH, ComboBrush);
9600 return D_O_K;
9601 }
9602
9603 void follow_twarp(int warpindex)
9604 {
9605 if(warpindex >= 4)
9606 {
9607 InfoDialog("Random Tile Warp",
9608 "This is a random tile warp combo, so it chooses"
9609 " randomly between the screen's four Tile Warps.").show();
9610 warpindex=zc_oldrand()&3;
9611 }
9612
9613 int32_t tm = Map.getCurrMap();
9614 int32_t ts = Map.getCurrScr();
9615 int32_t wt = Map.CurrScr()->tilewarptype[warpindex];
9616
9617 if(wt==wtCAVE || wt==wtNOWARP)
9618 {
9619 char buf[56];
9620 InfoDialog(warptype_string[wt],fmt::format("This screen's Tile Warp {} is set to {}, so it doesn't lead to another screen.",'A'+warpindex,warptype_string[wt]));
9621 return;
9622 }
9623
9624 Map.dowarp(0,warpindex);
9625
9626 if(ts!=Map.getCurrScr() || tm!=Map.getCurrMap())
9627 {
9628 FlashWarpSquare = (TheMaps[tm*MAPSCRS+ts].warpreturnc>>(warpindex*2))&3;
9629 FlashWarpClk = 32;
9630 }
9631 }
9632 void edit_twarp(int warpindex)
9633 {
9634 if(warpindex>=4)
9635 {
9636 InfoDialog("Random Tile Warp",
9637 "This is a random tile warp combo, so it chooses"
9638 " randomly between the screen's four Tile Warps.").show();
9639 warpindex=zc_oldrand()&3;
9640 }
9641
9642 if(warpindex > -1 && warpindex < 4)
9643 onTileWarpIndex(warpindex);
9644 }
9645
9646 int toggle_linked_scrolling()
9647 {
9648 LinkedScroll = LinkedScroll ? 0 : 1;
9649 zc_set_config("zquest","linked_comboscroll",LinkedScroll);
9650 return D_O_K;
9651 }
9652 void on_scroll_cpane()
9653 {
9654 switch (draw_mode)
9655 {
9656 case dm_alias:
9657 combo_alistpos[current_comboalist] = scrollto_alias(combo_apos);
9658 break;
9659 case dm_cpool:
9660 combo_pool_listpos[current_cpoollist] = scrollto_cpool(combo_pool_pos);
9661 break;
9662 case dm_auto:
9663 combo_auto_listpos[current_cautolist] = scrollto_cauto(combo_auto_pos);
9664 break;
9665 default:
9666 First[current_combolist] = scrollto_cmb(Combo);
9667 break;
9668 }
9669 }
9670 void on_edit_cpane()
9671 {
9672 switch (draw_mode)
9673 {
9674 case dm_alias:
9675 onEditComboAlias();
9676 break;
9677 case dm_cpool:
9678 onEditComboPool();
9679 break;
9680 case dm_auto:
9681 onEditAutoCombo();
9682 break;
9683 default:
9684 reset_combo_animations();
9685 reset_combo_animations2();
9686 edit_combo(Combo, true, CSet);
9687 setup_combo_animations();
9688 setup_combo_animations2();
9689 break;
9690 }
9691 }
9692 void open_combo_pages(optional<int> cid)
9693 {
9694 int cmb_id = cid ? *cid : 0;
9695 combo_screen(cmb_id >> 8, cmb_id);
9696 }
9697 void on_cpane_page()
9698 {
9699 switch(draw_mode)
9700 {
9701 case dm_normal:
9702 open_combo_pages(Combo);
9703 break;
9704 case dm_alias:
9705 call_alias_pages(combo_apos);
9706 break;
9707 case dm_auto:
9708 call_autoc_pages(combo_auto_pos);
9709 break;
9710 case dm_cpool:
9711 call_cpool_pages(combo_pool_pos);
9712 break;
9713 }
9714 }
9715 void open_cpane_tilepage()
9716 {
9717 onGotoTiles(combobuf[Combo].o_tile);
9718 }
9719 static int _clicked_fav = 0;
9720 void fav_rc_remove()
9721 {
9722 favorite_combo_modes[_clicked_fav] = dm_normal;
9723 favorite_combos[_clicked_fav] = -1;
9724 mark_save_dirty();
9725 }
9726 void popup_favorites_rc(int f, int x, int y)
9727 {
9728 _clicked_fav = f;
9729 string type;
9730 switch (draw_mode)
9731 {
9732 case dm_alias:
9733 type = "Alias";
9734 break;
9735 case dm_cpool:
9736 type = "Pool";
9737 break;
9738 case dm_auto:
9739 type = "Autocombo";
9740 break;
9741 case dm_normal:
9742 type = "Combo";
9743 break;
9744 default: return;
9745 }
9746 NewMenu rcmenu
9747 {
9748 { fmt::format("Scroll to {}", type), on_scroll_cpane },
9749 { fmt::format("Edit {}", type), on_edit_cpane },
9750 { fmt::format("Open {} Page", type), on_cpane_page },
9751 { fmt::format("Remove Fav {}", type), fav_rc_remove },
9752 };
9753 switch (draw_mode)
9754 {
9755 case dm_normal:
9756 rcmenu.add({
9757 {},
9758 { "Open Tile Page", open_cpane_tilepage },
9759 });
9760 break;
9761 }
9762 rcmenu.pop(x, y);
9763 }
9764 void popup_cpane_rc(int x, int y)
9765 {
9766 string type;
9767 switch (draw_mode)
9768 {
9769 case dm_alias:
9770 type = "Alias";
9771 break;
9772 case dm_cpool:
9773 type = "Pool";
9774 break;
9775 case dm_auto:
9776 type = "Autocombo";
9777 break;
9778 case dm_normal:
9779 type = "Combo";
9780 break;
9781 default: return;
9782 }
9783 NewMenu rcmenu;
9784 switch(draw_mode)
9785 {
9786 case dm_normal:
9787 rcmenu.add({
9788 { fmt::format("Edit {}", type), on_edit_cpane },
9789 { fmt::format("Open {} Page", type), on_cpane_page },
9790 { "Open Tile Page", open_cpane_tilepage },
9791 { "Combo Locations", onComboLocationReport },
9792 {},
9793 { "Scroll to Page...", onGotoPage },
9794 { "Linked Scrolling", toggle_linked_scrolling, nullopt, LinkedScroll ? MFL_SEL : 0 },
9795 });
9796 break;
9797 case dm_alias:
9798 case dm_cpool:
9799 case dm_auto:
9800 rcmenu.add({
9801 { fmt::format("Edit {}", type), on_edit_cpane },
9802 { fmt::format("Open {} Page", type), on_cpane_page },
9803 {},
9804 { "Scroll to Page...", onGotoPage },
9805 { "Linked Scrolling", toggle_linked_scrolling, nullopt, LinkedScroll ? MFL_SEL : 0 },
9806 });
9807 break;
9808 }
9809 rcmenu.pop(x, y);
9810 }
9811
9812 void set_brush_width(int32_t width)
9813 {
9814 BrushWidth = width;
9815 for(int q = 0; q < brush_width_menu.size(); ++q)
9816 brush_width_menu.at(q)->select(q==BrushWidth-1);
9817 refresh(rALL);
9818 }
9819
9820 void set_brush_height(int32_t height)
9821 {
9822 BrushHeight = height;
9823 for(int q = 0; q < brush_height_menu.size(); ++q)
9824 brush_height_menu.at(q)->select(q==BrushHeight-1);
9825 refresh(rALL);
9826 }
9827
9828 1 void restore_mouse()
9829 {
9830 1 ComboBrushPause=1;
9831 1 MouseSprite::set(ZQM_NORMAL);
9832 1 }
9833
9834 static int32_t comboa_cnt=0;
9835 static int32_t combop_cnt=0;
9836 static int32_t layer_cnt=0;
9837
9838 static char paste_ffc_menu_text[21];
9839 static char paste_ffc_menu_text2[21];
9840 static char follow_warp_menu_text[21];
9841 static char follow_warp_menu_text2[21];
9842
9843 static int fake_mouse_b(){return 0;}
9844 static int (*mouseb_proc)();
9845 static bool killed_mouse = false;
9846 void zq_killmouse()
9847 {
9848 if(killed_mouse) return;
9849 mouseb_proc = gui_mouse_b;
9850 gui_mouse_b = fake_mouse_b;
9851 killed_mouse = true;
9852 }
9853 void zq_restoremouse()
9854 {
9855 if(!killed_mouse) return;
9856 gui_mouse_b = mouseb_proc;
9857 killed_mouse = false;
9858 }
9859
9860
9861 void domouse()
9862 {
9863 static int mouse_down = 0;
9864 static int32_t scrolldelay = 0;
9865 auto mousexy = zc_get_mouse();
9866 auto x = mousexy.first;
9867 auto y = mousexy.second;
9868 double startx=mapscreen_x+(showedges?(16*mapscreen_single_scale):0);
9869 double starty=mapscreen_y+(showedges?(16*mapscreen_single_scale):0);
9870 int32_t startxint=mapscreen_x+(showedges?int32_t(16*mapscreen_single_scale):0);
9871 int32_t startyint=mapscreen_y+(showedges?int32_t(16*mapscreen_single_scale):0);
9872 int32_t cx=(x-startx)/(16*mapscreen_single_scale);
9873 int32_t cy=(y-starty)/(16*mapscreen_single_scale);
9874 ComboPosition combo_pos = {cx, cy};
9875
9876 if (draw_mode == dm_auto)
9877 {
9878 if (combo_pos != mouse_combo_pos)
9879 combobrushoverride = get_autocombo_floating_cid(combo_pos, false);
9880 }
9881 else
9882 combobrushoverride = -1;
9883
9884 mouse_combo_pos = combo_pos;
9885 update_combobrush();
9886
9887 ++scrolldelay;
9888
9889 bool x_on_list = false;
9890 for(auto q = 0; q < num_combo_cols; ++q)
9891 {
9892 if((x>=combolist[q].x) && (x<combolist[q].x+(combolist[q].xscale*combolist[q].w)))
9893 {
9894 x_on_list = true;
9895 break;
9896 }
9897 }
9898 if(MouseScroll && x_on_list && (key[KEY_LSHIFT] || key[KEY_RSHIFT] || (scrolldelay&3)==0))
9899 {
9900 int32_t test_list=0;
9901
9902 for(test_list=0; test_list<num_combo_cols; ++test_list)
9903 {
9904 if((x>=combolist[test_list].x) && (x<combolist[test_list].x+(combolist[test_list].xscale*combolist[test_list].w)))
9905 {
9906 break;
9907 }
9908 }
9909
9910 if(test_list<num_combo_cols)
9911 {
9912 if(y>=combolist[test_list].y-mouse_scroll_h && y<=combolist[test_list].y && First[test_list])
9913 {
9914 if((CHECK_CTRL_CMD)&&(key[KEY_ALT] || key[KEY_ALTGR]))
9915 {
9916 First[test_list]=0;
9917 }
9918 else if(CHECK_CTRL_CMD)
9919 {
9920 First[test_list]-=zc_min(First[test_list],256);
9921 }
9922 else if(key[KEY_ALT] || key[KEY_ALTGR])
9923 {
9924 First[test_list]-=zc_min(First[test_list],(combolist[test_list].w*combolist[test_list].h));
9925 }
9926 else
9927 {
9928 First[test_list]-=zc_min(First[test_list],combolist[test_list].w);
9929 }
9930 }
9931
9932 if(y>=combolist[test_list].y+(combolist[test_list].h*combolist[test_list].yscale)-1 && y<combolist[test_list].y+(combolist[test_list].h*combolist[test_list].yscale)+mouse_scroll_h-1 && First[test_list]<(MAXCOMBOS-(combolist[test_list].w*combolist[test_list].h)))
9933 {
9934 int32_t offset = combolist[test_list].w*combolist[test_list].h;
9935
9936 if((CHECK_CTRL_CMD)&&(key[KEY_ALT] || key[KEY_ALTGR]))
9937 {
9938 First[test_list]=MAXCOMBOS-offset;
9939 }
9940 else if(CHECK_CTRL_CMD)
9941 {
9942 First[test_list] = zc_min(MAXCOMBOS-offset, First[test_list]+256);
9943 }
9944 else if(key[KEY_ALT] || key[KEY_ALTGR])
9945 {
9946 First[test_list] = zc_min(MAXCOMBOS-offset, First[test_list]+ offset);
9947 }
9948 else
9949 {
9950 First[test_list] = zc_min(MAXCOMBOS - offset, First[test_list] + combolist[test_list].w);
9951 }
9952 }
9953 }
9954 }
9955
9956 // The screen for this combo_pos, layer 0. Used to access ffcs.
9957 mapscr* scr = Map.Scr(combo_pos);
9958 // The screen for this combo_pos at the CurrentLayer. Could be same as scr.
9959 mapscr* draw_mapscr = scr && CurrentLayer ? Map.Scr(combo_pos, CurrentLayer) : scr;
9960 int c = combo_pos.truncate();
9961 set_active_visible_screen(scr);
9962
9963 //-------------
9964 //tooltip stuff
9965 //-------------
9966 if (active_visible_screen && isinRect(x,y,startxint,startyint,startxint+(256*mapscreen_screenunit_scale)-1,startyint+(176*mapscreen_screenunit_scale)-1))
9967 {
9968 static int mapscr_tooltip_id = ttip_register_id();
9969 bool did_ffttip = false;
9970 int num_ffcs = scr->numFFC();
9971 for(int32_t i=num_ffcs-1; i>=0; i--)
9972 if(scr->ffcs[i].data !=0 && (scr->ffcs[i].layer >= CurrentLayer || (!CurrentLayer && scr->ffcs[i].layer < 0) || (scr->ffcs[i].flags&ffc_overlay)))
9973 {
9974 int32_t ffx = scr->ffcs[i].x.getFloor() + active_visible_screen->dx * 256;
9975 int32_t ffy = scr->ffcs[i].y.getFloor() + active_visible_screen->dy * 176;
9976 int32_t ffw = scr->ffTileWidth(i)*16;
9977 int32_t ffh = scr->ffTileHeight(i)*16;
9978 int32_t cx2 = (x-startxint)/mapscreen_single_scale;
9979 int32_t cy2 = (y-startyint)/mapscreen_single_scale;
9980
9981 if(cx2 >= ffx && cx2 < ffx+ffw && cy2 >= ffy && cy2 < ffy+ffh)
9982 {
9983 // FFC tooltip
9984 if(tooltip_current_ffc != i)
9985 {
9986 clear_tooltip();
9987 }
9988
9989 tooltip_current_ffc = i;
9990 char msg[1024] = {0};
9991 auto& ff = scr->ffcs[i];
9992 sprintf(msg,"FFC: %d Combo: %d\nCSet: %d Type: %s\nScript: %s",
9993 i+1, ff.data,ff.data,
9994 combo_class_buf[combobuf[ff.data].type].name,
9995 (ff.script<=0 ? "(None)" : ffcmap[ff.script-1].scriptname.substr(0,400).c_str()));
9996 ttip_install(mapscr_tooltip_id, msg, startxint+(ffx*mapscreen_single_scale), startyint+(ffy*mapscreen_single_scale), ffw*mapscreen_single_scale, ffh*mapscreen_single_scale, x, y);
9997 did_ffttip = true;
9998 break;
9999 }
10000 }
10001 if(!did_ffttip)
10002 {
10003 if(unsigned(c) < 176 && draw_mapscr && !gui_mouse_b())
10004 {
10005 int cid = draw_mapscr->data[c];
10006 newcombo const& cmb = combobuf[cid];
10007 std::ostringstream oss;
10008 int cs = draw_mapscr->cset[c];
10009 int sflag = draw_mapscr->sflag[c];
10010 oss << "Pos: " << c
10011 << "\nCombo: " << cid
10012 << "\nCSet: " << cs;
10013 if(sflag || cmb.flag)
10014 oss << "\nFlags: " << sflag << ", " << (int)cmb.flag;
10015 if(cmb.type)
10016 oss << "\nCombo type: " << combo_class_buf[cmb.type].name;
10017 if(cmb.label[0])
10018 oss << "\nLabel: " << cmb.label;
10019 ttip_install(mapscr_tooltip_id, oss.str().c_str(), startxint+(cx*16*mapscreen_single_scale), startyint+(cy*16*mapscreen_single_scale), 16*mapscreen_single_scale, 16*mapscreen_single_scale, x, y);
10020 }
10021 }
10022 }
10023
10024 {
10025 size_and_pos* squares[4] = {&itemsqr_pos,&stairsqr_pos,&warparrival_pos,&flagsqr_pos};
10026 for(int32_t j=0; j<4; j++)
10027 {
10028 auto& square = *squares[j];
10029 if(square.rect(x,y))
10030 {
10031 char msg[160];
10032 sprintf(msg,
10033 j==0 ? "Item Location" :
10034 j==1 ? "Stairs Secret\nTriggered when a Trigger Push Block is pushed." :
10035 j==2 ? "Arrival Square\nPlayer's location when they begin/resume the game." :
10036 "Combo Flags");
10037 update_tooltip(x,y,square,msg);
10038 }
10039 }
10040
10041 // Warp Returns
10042 for(int32_t j=0; j<4; j++)
10043 {
10044 size_and_pos& wret = warpret_pos[j];
10045 if(wret.rect(x,y))
10046 {
10047 char msg[160];
10048 sprintf(msg,"Warp Return Square %c\nPlayer's destination after warping to this screen.",(char)('A'+j));
10049 update_tooltip(x,y,wret,msg);
10050 }
10051 }
10052
10053 // Enemies
10054 if(enemy_prev_pos.rect(x,y))
10055 {
10056 char msg[160];
10057 sprintf(msg,"Enemies that appear on this screen.");
10058 update_tooltip(x,y,enemy_prev_pos,msg);
10059 }
10060
10061 int32_t cmd = commands_list.rectind(x,y);
10062 if(cmd > -1)
10063 {
10064 update_tooltip(x,y,commands_list.subsquare(cmd),
10065 fmt::format("Fav Command {}: {}\n{}", cmd,
10066 get_hotkey_name(favorite_commands[cmd]),
10067 get_hotkey_helptext(favorite_commands[cmd])).c_str());
10068 }
10069 }
10070
10071 if(draw_mode==dm_alias)
10072 {
10073 for(int32_t j=0; j<num_combo_cols; ++j)
10074 {
10075 auto& sqr = comboaliaslist[j];
10076 auto ind = sqr.rectind(x,y);
10077 if(ind > -1)
10078 {
10079 auto c2=ind+combo_alistpos[j];
10080 char msg[80];
10081 sprintf(msg, "Combo alias %d", c2);
10082 update_tooltip(x,y,sqr.subsquare(ind), msg);
10083 }
10084 }
10085 }
10086 else if(draw_mode==dm_cpool)
10087 {
10088 for(int32_t j=0; j<num_combo_cols; ++j)
10089 {
10090 auto& sqr = comboaliaslist[j];
10091 auto ind = sqr.rectind(x,y);
10092 if(ind > -1)
10093 {
10094 auto c2=ind+combo_pool_listpos[j];
10095 char msg[80];
10096 sprintf(msg, "Combo Pool %d", c2);
10097 update_tooltip(x,y,sqr.subsquare(ind), msg);
10098 }
10099 }
10100 if(cpool_prev_visible && combopool_prevbtn.rect(x,y))
10101 {
10102 if(do_layer_button_reset(combopool_prevbtn.x,combopool_prevbtn.y,
10103 combopool_prevbtn.w,combopool_prevbtn.h,
10104 weighted_cpool ? "Weighted" : "Unweighted",0,true))
10105 {
10106 weighted_cpool = !weighted_cpool;
10107 }
10108 }
10109 }
10110 else if (draw_mode == dm_auto)
10111 {
10112 for (int32_t j = 0; j < num_combo_cols; ++j)
10113 {
10114 auto& sqr = comboaliaslist[j];
10115 auto ind = sqr.rectind(x, y);
10116 if (ind > -1)
10117 {
10118 auto c2 = ind + combo_auto_listpos[j];
10119 char msg[80];
10120 sprintf(msg, "Auto Combo %d", c2);
10121 update_tooltip(x, y, sqr.subsquare(ind), msg);
10122 }
10123 }
10124 }
10125 else
10126 {
10127 if(combo_preview.rect(x,y))
10128 {
10129 auto str = "Combo Colors:\n"+get_combo_colornames(Combo,CSet);
10130 update_tooltip(x,y,combo_preview,str.c_str());
10131 }
10132 else if(comboprev_buf[0] && combo_preview_text1.rect(x,y))
10133 {
10134 update_tooltip(x,y,combo_preview_text1,comboprev_buf);
10135 }
10136 else if(comboprev_buf2[0] && combo_preview_text2.rect(x,y))
10137 {
10138 update_tooltip(x,y,combo_preview_text2,comboprev_buf2);
10139 }
10140 else for(int32_t j=0; j<num_combo_cols; ++j)
10141 {
10142 auto& sqr = combolist[j];
10143 auto ind = sqr.rectind(x,y);
10144 if(ind > -1)
10145 {
10146 int32_t c2=ind+First[j];
10147 std::ostringstream oss;
10148 newcombo const& cmb = combobuf[c2];
10149 oss << "Combo " << c2 << ": " << combo_class_buf[cmb.type].name;
10150 if(cmb.flag != 0)
10151 oss << "\nInherent flag: " << ZI.getMapFlagName(cmb.flag);
10152 if(!cmb.label.empty())
10153 oss << "\nLabel: " << cmb.label;
10154
10155 update_tooltip(x,y,sqr.subsquare(ind), oss.str().c_str());
10156 }
10157 }
10158 }
10159
10160 if (favorites_list.rect(x, y))
10161 {
10162 int32_t f = favorites_list.rectind(x, y);
10163 int32_t row = f / favorites_list.w;
10164 int32_t col = f % favorites_list.w;
10165 f = (row * FAVORITECOMBO_PER_ROW) + col;
10166
10167 auto& sqr = favorites_list.subsquare(col, row);
10168
10169 char buf[180];
10170 if (favorite_combos[f] == -1)
10171 sprintf(buf, "Fav Combo %d\nEmpty", f);
10172 else
10173 {
10174 switch (favorite_combo_modes[f])
10175 {
10176 case dm_alias:
10177 sprintf(buf, "Fav Combo %d\nAlias %d", f, favorite_combos[f]);
10178 break;
10179 case dm_cpool:
10180 sprintf(buf, "Fav Combo %d\nPool %d", f, favorite_combos[f]);
10181 break;
10182 case dm_auto:
10183 sprintf(buf, "Fav Combo %d\nAutocombo %d", f, favorite_combos[f]);
10184 break;
10185 default:
10186 sprintf(buf, "Fav Combo %d\nCombo %d", f, favorite_combos[f]);
10187 }
10188 }
10189 update_tooltip(x, y, sqr, buf);
10190 }
10191
10192 size_and_pos const& real_mini = zoomed_minimap ? real_minimap_zoomed : real_minimap;
10193 auto ind = real_mini.rectind(x,y);
10194 if(ind > -1)
10195 {
10196 char buf[80];
10197 sprintf(buf,"0x%02X (%d)", ind, ind);
10198 ttip_install(minimap_tooltip_id, buf, real_mini.subsquare(ind), real_mini.x+real_mini.tw(), real_mini.y-16);
10199 ttip_set_highlight_thickness(minimap_tooltip_id, zoomed_minimap ? 2 : 1);
10200 // Make sure always above the other tooltip items to the right of the map (even in big map mode).
10201 ttip_set_z_index(minimap_tooltip_id, 100);
10202 ttip_clear_timer();
10203 }
10204 else
10205 {
10206 ttip_uninstall(minimap_tooltip_id);
10207 }
10208
10209 // Mouse clicking stuff
10210 int real_mb = gui_mouse_b();
10211 int mb = real_mb & ~mouse_down; //Only handle clicks that have not been handled already
10212 auto mz = mouse_z;
10213 bool lclick = mb&1;
10214 bool rclick = mb&2;
10215
10216 FONT* tfont = font;
10217 if(zoomed_minimap)
10218 {
10219 if((lclick||rclick) && !minimap_zoomed.rect(x,y))
10220 {
10221 // 'Clicked off'
10222 mmap_set_zoom(false);
10223 goto domouse_doneclick;
10224 }
10225 }
10226
10227 if(real_mb==0)
10228 {
10229 mouse_down = 0;
10230 canfill=true;
10231 }
10232 else if(lclick || rclick)
10233 {
10234 //on the minimap
10235 if(real_mini.rect(x,y))
10236 {
10237 if(lclick)
10238 select_scr();
10239 else if(rclick && !(mouse_down&2))
10240 {
10241 mmap_set_zoom(!zoomed_minimap);
10242 }
10243 goto domouse_doneclick;
10244 }
10245
10246 if(zoomed_minimap && minimap_zoomed.rect(x,y))
10247 goto domouse_doneclick; //Eat clicks
10248
10249 //on the map tabs
10250 font = get_custom_font(CFONT_GUI);
10251 for(int32_t btn=0; btn<mappage_count; ++btn)
10252 {
10253 if (btn == current_mappage) continue;
10254 char tbuf[15];
10255 sprintf(tbuf, "%d:%02X", map_page[btn].map+1, map_page[btn].screen);
10256 auto& sqr = map_page_bar[btn];
10257 if(sqr.rect(x,y))
10258 {
10259 if(do_layer_button_reset(sqr.x,sqr.y,sqr.w,sqr.h,tbuf,(btn==current_mappage?D_SELECTED:0)))
10260 {
10261 draw_layer_button(screen, sqr.x,sqr.y,sqr.w,sqr.h,tbuf,D_SELECTED);
10262
10263 if (lclick)
10264 {
10265 map_page[current_mappage].map=Map.getCurrMap();
10266 map_page[current_mappage].screen=Map.getCurrScr();
10267 current_mappage=btn;
10268 Map.setCurrMap(map_page[current_mappage].map);
10269 Map.setCurrScr(map_page[current_mappage].screen);
10270 rebuild_trans_table(); //Woo
10271 }
10272 else if (rclick)
10273 {
10274 map_page[btn].map = 0;
10275 map_page[btn].screen = 0;
10276 }
10277 }
10278 goto domouse_doneclick;
10279 }
10280 }
10281
10282 if(compactbtn.rect(x,y))
10283 {
10284 if(do_text_button(compactbtn.x, compactbtn.y, compactbtn.w, compactbtn.h, is_compact ? "< Expand" : "> Compact"));
10285 toggle_is_compact();
10286 goto domouse_doneclick;
10287 }
10288
10289 if(!zoom_in_btn_disabled && zoominbtn.rect(x,y))
10290 {
10291 if(do_text_button(zoominbtn.x, zoominbtn.y, zoominbtn.w, zoominbtn.h, "+"))
10292 change_mapscr_zoom(-1);
10293 goto domouse_doneclick;
10294 }
10295
10296 if(!zoom_out_btn_disabled && zoomoutbtn.rect(x,y))
10297 {
10298 if(do_text_button(zoomoutbtn.x, zoomoutbtn.y, zoomoutbtn.w, zoomoutbtn.h, "-"))
10299 change_mapscr_zoom(1);
10300 goto domouse_doneclick;
10301 }
10302
10303 font = get_zc_font(font_lfont_l);
10304 if(combo_merge_btn.rect(x,y))
10305 {
10306 bool merged = is_compact ? compact_merged_combopane : large_merged_combopane;
10307 if(do_text_button(combo_merge_btn.x,combo_merge_btn.y,combo_merge_btn.w,combo_merge_btn.h,merged ? "<|>" : ">|<"))
10308 {
10309 toggle_merged_mode();
10310 }
10311 goto domouse_doneclick;
10312 }
10313
10314 if(favorites_zoombtn.rect(x,y))
10315 {
10316 bool zoomed = is_compact ? compact_zoomed_fav : large_zoomed_fav;
10317 if(do_text_button(favorites_zoombtn.x,favorites_zoombtn.y,favorites_zoombtn.w,favorites_zoombtn.h,zoomed ? "-" : "+"))
10318 {
10319 toggle_favzoom_mode();
10320 }
10321 goto domouse_doneclick;
10322 }
10323 else if(favorites_x.rect(x,y))
10324 {
10325 if(do_text_button(favorites_x.x,favorites_x.y,favorites_x.w,favorites_x.h,"X"))
10326 {
10327 if (alert_confirm("Clear Favorite Combos", "Are you sure you want"
10328 " to clear all favorite combos?"))
10329 {
10330 for(auto q = 0; q < MAXFAVORITECOMBOS; ++q)
10331 {
10332 favorite_combos[q] = -1;
10333 favorite_combo_modes[q] = dm_normal;
10334 }
10335 mark_save_dirty();
10336 refresh(rFAVORITES);
10337 }
10338 }
10339 goto domouse_doneclick;
10340 }
10341 else if(favorites_infobtn.rect(x,y))
10342 {
10343 if(do_text_button(favorites_infobtn.x,favorites_infobtn.y,favorites_infobtn.w,favorites_infobtn.h,"?"))
10344 {
10345 InfoDialog("Favorite Combos",
10346 "On LClick (empty): Sets clicked favorite to the current combo."
10347 "\nOn LClick: Sets current combo to clicked favorite."
10348 "\nShift+LClick: Sets clicked favorite to current combo."
10349 "\nCtrl+LClick: Clears clicked favorite."
10350 "\nAlt+LClick: Scrolls to clicked favorite."
10351 "\nRClick: Opens context menu."
10352 "\n\nClick the Page buttons (<-/->) to cycle between pages (RClick to jump to a page)"
10353 "\nClick the Zoom button (+/-) to toggle zoom level."
10354 "\nClick the X button to clear all favorite combos.").show();
10355 }
10356 goto domouse_doneclick;
10357 }
10358 else if(favorites_pgleft.rect(x,y))
10359 {
10360 if (do_text_button(favorites_pgleft.x, favorites_pgleft.y, favorites_pgleft.w, favorites_pgleft.h, is_compact ? "<" : "<-"))
10361 {
10362 if (rclick)
10363 {
10364 if(auto val = popup_num_menu(x, y, 1, 9, FavoriteComboPage, [](int p){return fmt::format("Page {}",p);}))
10365 FavoriteComboPage = vbound(*val-1, 0, 8);
10366 }
10367 else
10368 FavoriteComboPage = FavoriteComboPage == 0 ? 8 : --FavoriteComboPage;
10369 reload_zq_gui();
10370 }
10371 goto domouse_doneclick;
10372 }
10373 else if(favorites_pgright.rect(x,y))
10374 {
10375 if (do_text_button(favorites_pgright.x, favorites_pgright.y, favorites_pgright.w, favorites_pgright.h, is_compact ? ">" : "->"))
10376 {
10377 if (rclick)
10378 {
10379 if(auto val = popup_num_menu(x, y, 1, 9, FavoriteComboPage, [](int p){return fmt::format("Page {}",p);}))
10380 FavoriteComboPage = vbound(*val-1, 0, 8);
10381 }
10382 else
10383 FavoriteComboPage = FavoriteComboPage == 8 ? 0 : ++FavoriteComboPage;
10384 reload_zq_gui();
10385 }
10386 goto domouse_doneclick;
10387 }
10388
10389 if(commands_zoombtn.rect(x,y))
10390 {
10391 bool zoomed = is_compact ? compact_zoomed_cmd : large_zoomed_cmd;
10392 if(do_text_button(commands_zoombtn.x,commands_zoombtn.y,commands_zoombtn.w,commands_zoombtn.h,zoomed ? "-" : "+"))
10393 {
10394 toggle_cmdzoom_mode();
10395 }
10396 goto domouse_doneclick;
10397 }
10398 else if(commands_x.rect(x,y))
10399 {
10400 if(do_text_button(commands_x.x,commands_x.y,commands_x.w,commands_x.h,"X"))
10401 {
10402 if (alert_confirm("Clear Favorite Commands", "Are you sure you want"
10403 " to clear all favorite commands?"))
10404 {
10405 for(auto q = 0; q < MAXFAVORITECOMMANDS; ++q)
10406 write_fav_command(q,0);
10407 refresh(rFAVORITES);
10408 }
10409 }
10410 goto domouse_doneclick;
10411 }
10412 else if(commands_infobtn.rect(x,y))
10413 {
10414 if(do_text_button(commands_infobtn.x,commands_infobtn.y,commands_infobtn.w,commands_infobtn.h,"?"))
10415 {
10416 InfoDialog("Favorite Commands",
10417 "On LClick (empty): Choose a favorite command"
10418 "\nOn LClick: Runs the favorite command"
10419 "\nShift+Click: Choose a favorite command"
10420 "\nRClick: Choose a favorite command"
10421 "\nCtrl+Click: Clears clicked command"
10422 "\nAlt+Click: Shows info on the favorite command"
10423 "\n\nClick the Zoom button (+/-) to toggle zoom level"
10424 "\nClick the X button to clear all favorite commands").show();
10425 }
10426 goto domouse_doneclick;
10427 }
10428 font=tfont;
10429
10430 // On the layer panel
10431 font = get_custom_font(CFONT_GUI);
10432 for(int32_t i=0; i<=6; ++i)
10433 {
10434 int32_t spacing_offs = is_compact ? 2 : 10;
10435 int32_t rx = (i * (layerpanel_buttonwidth+spacing_offs+layerpanel_checkbox_wid)) + layer_panel.x+(is_compact?2:6);
10436 int32_t ry = layer_panel.y;
10437
10438 if (i != CurrentLayer && (i == 0 || mapscreen_valid_layers[i - 1]) && isinRect(x,y,rx,ry,rx+layerpanel_buttonwidth-1,ry+layerpanel_buttonheight-1))
10439 {
10440 char tbuf[15];
10441
10442 if (Map.getViewSize() > 1)
10443 {
10444 sprintf(tbuf, "%d", i);
10445 }
10446 else if (i != 0 && mapscreen_valid_layers[i - 1])
10447 {
10448 if (is_compact)
10449 {
10450 sprintf(tbuf, "%s%d %d:%02X",
10451 (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"",
10452 i, Map.CurrScr()->layermap[i-1], Map.CurrScr()->layerscreen[i-1]);
10453 }
10454 else
10455 {
10456 sprintf(tbuf, "%s%d (%d:%02X)",
10457 (i==2 && Map.CurrScr()->flags7&fLAYER2BG) || (i==3 && Map.CurrScr()->flags7&fLAYER3BG) ? "-":"",
10458 i, Map.CurrScr()->layermap[i-1], Map.CurrScr()->layerscreen[i-1]);
10459 }
10460 }
10461 else
10462 {
10463 sprintf(tbuf, "%d", i);
10464 }
10465
10466 if(do_text_button(rx, ry, layerpanel_buttonwidth, layerpanel_buttonheight, tbuf))
10467 {
10468 CurrentLayer = i;
10469 goto domouse_doneclick;
10470 }
10471 }
10472
10473 auto cbyofs = (layerpanel_buttonheight-layerpanel_checkbox_hei)/2;
10474 if(isinRect(x,y,rx+layerpanel_buttonwidth+1,ry+cbyofs,rx+layerpanel_buttonwidth+1+layerpanel_checkbox_wid-1,ry+2+layerpanel_checkbox_hei-1))
10475 {
10476 do_checkbox(screen,rx+layerpanel_buttonwidth+1,ry+cbyofs,layerpanel_checkbox_wid,layerpanel_checkbox_hei,LayerMaskInt[i]);
10477 goto domouse_doneclick;
10478 }
10479 }
10480 font=tfont;
10481
10482 //Uses lclick/rclick separately
10483
10484 //on the map screen
10485 if(isinRect(x,y,startxint,startyint,startxint+(256*mapscreen_screenunit_scale)-1,startyint+(176*mapscreen_screenunit_scale)-1))
10486 {
10487 if (lclick)
10488 {
10489 Map.setCurrScr(Map.getScreenForPosition(combo_pos));
10490 }
10491
10492 if (draw_mode == dm_auto)
10493 {
10494 if (CHECK_CTRL_CMD)
10495 {
10496 if (canfill)
10497 {
10498 switch (fill_type)
10499 {
10500 case 0:
10501 flood();
10502 break;
10503
10504 case 1:
10505 fill_4();
10506 break;
10507
10508 case 2:
10509 fill_8();
10510 break;
10511
10512 case 3:
10513 fill2_4();
10514 break;
10515
10516 case 4:
10517 fill2_8();
10518 break;
10519 }
10520
10521 canfill = false;
10522 }
10523 }
10524 else
10525 draw(key[KEY_LSHIFT] || key[KEY_RSHIFT]);
10526 }
10527 else if (scr && lclick)
10528 {
10529 int32_t cx2 = (x-startxint)/mapscreen_single_scale;
10530 int32_t cy2 = (y-startyint)/mapscreen_single_scale;
10531
10532 // Move items
10533 if (scr->hasitem && active_visible_screen)
10534 {
10535 int32_t ix = scr->itemx + active_visible_screen->dx * 256;
10536 int32_t iy = scr->itemy + active_visible_screen->dy * 176;
10537
10538 if(cx2 >= ix && cx2 < ix+16 && cy2 >= iy && cy2 < iy+16)
10539 doxypos(scr->itemx, scr->itemy, 11, SNAP_HALF, SNAP_NONE, true, 0, 0, 16, 16);
10540 }
10541
10542 // Move FFCs
10543 int num_ffcs = scr->numFFC();
10544 for(int32_t i=num_ffcs-1; i>=0; i--)
10545 if(scr->ffcs[i].data !=0 && (scr->ffcs[i].layer >= CurrentLayer || (!CurrentLayer && scr->ffcs[i].layer < 0) || (scr->ffcs[i].flags&ffc_overlay)))
10546 {
10547 int32_t ffx = scr->ffcs[i].x.getFloor() + active_visible_screen->dx * 256;
10548 int32_t ffy = scr->ffcs[i].y.getFloor() + active_visible_screen->dy * 176;
10549
10550 if(cx2 >= ffx && cx2 < ffx+(scr->ffTileWidth(i)*16) && cy2 >= ffy && cy2 < ffy+(scr->ffTileHeight(i)*16))
10551 {
10552 moveffc(i, cx2, cy2);
10553 break;
10554 }
10555 }
10556
10557 if(key[KEY_ALT]||key[KEY_ALTGR])
10558 {
10559 if (!draw_mapscr) return;
10560
10561 Combo=draw_mapscr->data[c];
10562 if(AutoBrush)
10563 BrushWidth = BrushHeight = 1;
10564 if(key[KEY_LSHIFT]||key[KEY_RSHIFT])
10565 CSet=draw_mapscr->cset[c];
10566 if(CHECK_CTRL_CMD)
10567 First[current_combolist]=scrollto_cmb(draw_mapscr->data[c]);
10568 }
10569 else if(CHECK_CTRL_CMD)
10570 {
10571 if(canfill)
10572 {
10573 switch(fill_type)
10574 {
10575 case 0:
10576 flood();
10577 break;
10578
10579 case 1:
10580 fill_4();
10581 break;
10582
10583 case 2:
10584 fill_8();
10585 break;
10586
10587 case 3:
10588 fill2_4();
10589 break;
10590
10591 case 4:
10592 fill2_8();
10593 break;
10594 }
10595
10596 canfill=false;
10597 }
10598 }
10599 else draw(key[KEY_LSHIFT] || key[KEY_RSHIFT]);
10600 }
10601 else if (scr && rclick)
10602 {
10603 ComboBrushPause=1;
10604 refresh(rMAP);
10605 restore_mouse();
10606 ComboBrushPause=0;
10607
10608 bool clickedffc = false;
10609
10610 // FFC right-click menu
10611 // This loop also serves to find the free ffc with the smallest slot number.
10612 int num_ffcs = scr->numFFC();
10613 uint32_t earliestfreeffc = num_ffcs;
10614 for(int32_t i=num_ffcs-1; i>=0; i--)
10615 {
10616 auto data = scr->ffcs[i].data;
10617 if(data==0)
10618 {
10619 if(i < earliestfreeffc)
10620 earliestfreeffc = i;
10621 continue;
10622 }
10623
10624 if(clickedffc || !(scr->valid&mVALID))
10625 continue;
10626
10627 if(data!=0 && (scr->ffcs[i].layer >= CurrentLayer || (!CurrentLayer && scr->ffcs[i].layer < 0) || (scr->ffcs[i].flags&ffc_overlay)))
10628 {
10629 int32_t ffx = scr->ffcs[i].x.getFloor() + active_visible_screen->dx * 256;
10630 int32_t ffy = scr->ffcs[i].y.getFloor() + active_visible_screen->dy * 176;
10631 int32_t cx2 = (x-startxint)/mapscreen_single_scale;
10632 int32_t cy2 = (y-startyint)/mapscreen_single_scale;
10633
10634 if(cx2 >= ffx && cx2 < ffx+(scr->ffTileWidth(i)*16) && cy2 >= ffy && cy2 < ffy+(scr->ffTileHeight(i)*16))
10635 {
10636 auto& ffc = scr->ffcs[i];
10637 NewMenu rcmenu
10638 {
10639 { "Copy FFC", [&](){Map.CopyFFC(active_visible_screen->screen, i);} },
10640 { "Paste FFC data", [&]()
10641 {
10642 if(alert_confirm("Confirm Paste", "Really replace the FFC with"
10643 " the data of the copied FFC?"))
10644 {
10645 auto set_ffc_data = Map.getCopyFFCData();
10646 set_ffc_data.x = scr->ffcs[i].x;
10647 set_ffc_data.y = scr->ffcs[i].y;
10648 Map.DoSetFFCCommand(Map.getCurrMap(), active_visible_screen->screen, i, set_ffc_data);
10649 }
10650 }, nullopt, Map.getCopyFFC() < 0 ? MFL_DIS : 0 },
10651 { "Edit FFC", [&](){call_ffc_dialog(i, active_visible_screen->scr, active_visible_screen->screen);} },
10652 { "Clear FFC", [&]()
10653 {
10654 if (alert_confirm("Confirm Clear", "Really clear this Freeform Combo?"))
10655 {
10656 Map.DoSetFFCCommand(Map.getCurrMap(), active_visible_screen->screen, i, {
10657 .x = 0,
10658 .y = 0,
10659 .vx = 0,
10660 .vy = 0,
10661 .ax = 0,
10662 .ay = 0,
10663 .data = 0,
10664 .cset = 0,
10665 .delay = 0,
10666 .link = 0,
10667 .script = 0,
10668 .tw = 1,
10669 .th = 1,
10670 .ew = 16,
10671 .eh = 16,
10672 .flags = ffc_none,
10673 .initd = 0,
10674 });
10675 mark_save_dirty();
10676 }
10677 } },
10678 { "Snap to Grid", [&]()
10679 {
10680 int oldffx = scr->ffcs[i].x.getInt();
10681 int oldffy = scr->ffcs[i].y.getInt();
10682 int pos = COMBOPOS(oldffx,oldffy);
10683 int newffy = COMBOY(pos);
10684 int newffx = COMBOX(pos);
10685
10686 auto set_ffc_data = set_ffc_command::create_data(scr->ffcs[i]);
10687 set_ffc_data.x = newffx;
10688 set_ffc_data.y = newffy;
10689 Map.DoSetFFCCommand(Map.getCurrMap(), active_visible_screen->screen, i, set_ffc_data);
10690
10691 mark_save_dirty();
10692 } },
10693 {},
10694 { "Select Combo", [&]()
10695 {
10696 Combo = ffc.data;
10697 } },
10698 { "Scroll to Combo", [&]()
10699 {
10700 First[current_combolist] = scrollto_cmb(ffc.data);
10701 } },
10702 { "Open Combo Page", [&]()
10703 {
10704 open_combo_pages(ffc.data);
10705 } },
10706 { "Edit Combo", [&]()
10707 {
10708 edit_combo(ffc.data,true,ffc.cset);
10709 } },
10710 };
10711 rcmenu.pop(x, y);
10712 clickedffc = true;
10713 break;
10714 }
10715 }
10716 }
10717
10718 // Combo right-click menu
10719 if(!clickedffc)
10720 {
10721 int warpindex = Map.warpindex(scr->data[c]);
10722 string txt_twarp_follow, txt_twarp_edit, txt_ffc_edit, txt_ffc_paste;
10723 bool show_ffcs = earliestfreeffc < MAXFFCS;
10724 bool dis_paste_ffc = Map.getCopyFFC() < 0;
10725 bool show_warps = warpindex > -1;
10726 bool show_warpback = Map.has_warpback();
10727 // FFC-specific options
10728 if(earliestfreeffc < MAXFFCS)
10729 {
10730 txt_ffc_edit = fmt::format("Edit New FFC {}",earliestfreeffc+1);
10731 if(Map.getCopyFFC()>-1)
10732 txt_ffc_paste = fmt::format("Paste FFC as FFC {}",earliestfreeffc+1);
10733 else
10734 txt_ffc_paste = "Paste FFC";
10735 }
10736
10737 if(warpindex > -1)
10738 {
10739 char letter = warpindex==4 ? 'R' : 'A'+warpindex;
10740 txt_twarp_follow = fmt::format("Follow Tile Warp {}",letter);
10741 txt_twarp_edit = fmt::format("Edit Tile Warp {}",letter);
10742 }
10743
10744 NewMenu draw_rc_menu
10745 {
10746 { "Select Combo", [&]()
10747 {
10748 Combo = draw_mapscr->data[c];
10749 if(AutoBrush)
10750 BrushWidth = BrushHeight = 1;
10751 }, nullopt, !draw_mapscr },
10752 { "Scroll to Combo", [&]()
10753 {
10754 First[current_combolist] = scrollto_cmb(draw_mapscr->data[c]);
10755 }, nullopt, !draw_mapscr },
10756 { "Open Combo Page", [&]()
10757 {
10758 open_combo_pages(draw_mapscr->data[c]);
10759 }, nullopt, !draw_mapscr },
10760 { "Edit Combo", [&]()
10761 {
10762 edit_combo(draw_mapscr->data[c],true,draw_mapscr->cset[c]);
10763 }, nullopt, !draw_mapscr },
10764 {},
10765 { "Replace All", [&](){replace(combo_pos);} },
10766 { "Draw Block", &draw_block_menu },
10767 { "Brush Settings ", &brush_menu },
10768 { "Set Fill Type ", &fill_menu },
10769 };
10770 if(show_warps || show_warpback)
10771 {
10772 draw_rc_menu.add_sep();
10773 if(show_warpback)
10774 draw_rc_menu.add({ "Warp Back", [&](){Map.warpback();} });
10775 if(show_warps)
10776 {
10777 draw_rc_menu.add({ txt_twarp_follow, [&](){follow_twarp(warpindex);} });
10778 draw_rc_menu.add({ txt_twarp_edit, [&](){edit_twarp(warpindex);} });
10779 }
10780 }
10781 if(show_ffcs)
10782 {
10783 draw_rc_menu.add_sep();
10784 draw_rc_menu.add({ txt_ffc_edit, [&]()
10785 {
10786 ffdata tempdat;
10787 // x, y are ints on ffdata (but ffc x, y are zfix), so *10000
10788 tempdat.x = ((int((x-startxint)/mapscreen_single_scale)&(~0x0007)) % 256) * 10000;
10789 tempdat.y = ((int((y-startyint)/mapscreen_single_scale)&(~0x0007)) % 176) * 10000;
10790 tempdat.data = Combo;
10791 tempdat.cset = CSet;
10792 if (SmartFFCPlacement)
10793 {
10794 tempdat.layer = CurrentLayer;
10795 SETFLAG(tempdat.flags, ffc_solid, (combobuf[Combo].walk & 0xF) == 0xF);
10796 }
10797 call_ffc_dialog(earliestfreeffc, tempdat, active_visible_screen->scr, active_visible_screen->screen);
10798 } });
10799 draw_rc_menu.add({ txt_ffc_paste, [&]()
10800 {
10801 auto set_ffc_data = Map.getCopyFFCData();
10802 set_ffc_data.x = ((int((x-startxint)/mapscreen_single_scale)&(~0x0007)) % 256);
10803 set_ffc_data.y = ((int((y-startyint)/mapscreen_single_scale)&(~0x0007)) % 176);
10804 Map.DoSetFFCCommand(Map.getCurrMap(), active_visible_screen->screen, earliestfreeffc, set_ffc_data);
10805 }, nullopt, dis_paste_ffc });
10806 }
10807 draw_rc_menu.add_sep();
10808 draw_rc_menu.add({ "Screen", &rc_menu_screen });
10809 draw_rc_menu.pop(x,y);
10810 }
10811 }
10812 goto domouse_doneclick;
10813 }
10814
10815 //on the drawing mode button
10816 font = get_custom_font(CFONT_GUI);
10817 if(drawmode_btn.rect(x,y))
10818 {
10819 if(lclick)
10820 {
10821 if(do_text_button(drawmode_btn.x,drawmode_btn.y,drawmode_btn.w,drawmode_btn.h,dm_names[draw_mode]))
10822 onDrawingMode();
10823 }
10824 else if(rclick)
10825 drawing_mode_menu.pop(x,y);
10826 goto domouse_doneclick;
10827 }
10828 font=tfont;
10829
10830 //Squares
10831 //
10832 set_active_visible_screen(Map.CurrScr());
10833 {
10834 if(squarepanel_swap_btn.rect(x,y))
10835 {
10836 toggle_compact_sqr_mode();
10837 goto domouse_doneclick;
10838 }
10839 if(squarepanel_up_btn.rect(x,y))
10840 {
10841 cycle_compact_sqr(false);
10842 goto domouse_doneclick;
10843 }
10844 if(squarepanel_down_btn.rect(x,y))
10845 {
10846 cycle_compact_sqr(true);
10847 goto domouse_doneclick;
10848 }
10849
10850 bool do_dummyxy = false;
10851 bool dummymode = key[KEY_LSHIFT] || key[KEY_RSHIFT];
10852
10853 if(itemsqr_pos.rect(x,y))
10854 {
10855 if(dummymode) do_dummyxy = true;
10856 else
10857 {
10858 onItem();
10859
10860 if(!rclick && Map.CurrScr()->hasitem)
10861 doxypos(Map.CurrScr()->itemx,Map.CurrScr()->itemy,11,SNAP_HALF,SNAP_NONE);
10862 goto domouse_doneclick;
10863 }
10864 }
10865
10866 if(stairsqr_pos.rect(x,y))
10867 {
10868 if(dummymode) do_dummyxy = true;
10869 else
10870 {
10871 doxypos(Map.CurrScr()->stairx,Map.CurrScr()->stairy,14,SNAP_WHOLE);
10872 goto domouse_doneclick;
10873 }
10874 }
10875
10876 if(warparrival_pos.rect(x,y))
10877 {
10878 if(dummymode) do_dummyxy = true;
10879 else
10880 {
10881 if(get_qr(qr_NOARRIVALPOINT))
10882 {
10883 info_dsa("Arrival Square",
10884 "The arrival square cannot be used unless the QR 'Use Warp Return "
10885 "Points Only' under 'Quest->Options->Combos' is disabled."
10886 "\nGenerally, this square only exists for compatibility purposes, and is not used"
10887 " in creating new quests.",
10888 "dsa_warparrival");
10889 }
10890 else doxypos(Map.CurrScr()->warparrivalx,Map.CurrScr()->warparrivaly,10,SNAP_HALF,SNAP_NONE);
10891 goto domouse_doneclick;
10892 }
10893 }
10894
10895 if(flagsqr_pos.rect(x,y))
10896 {
10897 if(dummymode) do_dummyxy = true;
10898 else
10899 {
10900 onFlags();
10901 goto domouse_doneclick;
10902 }
10903 }
10904
10905 for(auto q = 0; q < 4; ++q)
10906 {
10907 if(warpret_pos[q].rect(x,y))
10908 {
10909 if(dummymode) do_dummyxy = true;
10910 else
10911 {
10912 doxypos(Map.CurrScr()->warpreturnx[q],Map.CurrScr()->warpreturny[q],9,SNAP_HALF,SNAP_NONE);
10913 goto domouse_doneclick;
10914 }
10915 }
10916 }
10917
10918 if(enemy_prev_pos.rect(x,y))
10919 {
10920 if(dummymode) do_dummyxy = true;
10921 else
10922 {
10923 onEnemies();
10924 goto domouse_doneclick;
10925 }
10926 }
10927
10928 if(do_dummyxy)
10929 {
10930 byte x = 0, y = 0;
10931 showxypos_dummy = true;
10932 doxypos(x,y,13,SNAP_HALF,SNAP_NONE);
10933 goto domouse_doneclick;
10934 }
10935 }
10936
10937 if(draw_mode==dm_alias)
10938 {
10939 for(int32_t j=0; j<num_combo_cols; ++j)
10940 {
10941 if(combolistscrollers[j].rectind(x,y)==0 && !mouse_down)
10942 {
10943 scrollup(j);
10944 goto domouse_doneclick;
10945 }
10946 else if(combolistscrollers[j].rectind(x,y)==1 && !mouse_down)
10947 {
10948 scrolldown(j);
10949 goto domouse_doneclick;
10950 }
10951 else if(comboaliaslist[j].rect(x,y))
10952 {
10953 select_comboa(j);
10954
10955 if(rclick && comboaliaslist[j].rect(gui_mouse_x(),gui_mouse_y()))
10956 popup_cpane_rc(x, y);
10957 goto domouse_doneclick;
10958 }
10959 }
10960 }
10961 else if(draw_mode==dm_cpool)
10962 {
10963 for(int32_t j=0; j<num_combo_cols; ++j)
10964 {
10965 if(combolistscrollers[j].rectind(x,y)==0 && !mouse_down)
10966 {
10967 scrollup(j);
10968 goto domouse_doneclick;
10969 }
10970 else if(combolistscrollers[j].rectind(x,y)==1 && !mouse_down)
10971 {
10972 scrolldown(j);
10973 goto domouse_doneclick;
10974 }
10975 else if(comboaliaslist[j].rect(x,y))
10976 {
10977 select_combop(j);
10978
10979 if(rclick && comboaliaslist[j].rect(gui_mouse_x(),gui_mouse_y()))
10980 popup_cpane_rc(x, y);
10981 goto domouse_doneclick;
10982 }
10983 }
10984 }
10985 else if (draw_mode == dm_auto)
10986 {
10987 for (int32_t j = 0; j < num_combo_cols; ++j)
10988 {
10989 if (combolistscrollers[j].rectind(x, y) == 0 && !mouse_down)
10990 {
10991 scrollup(j);
10992 goto domouse_doneclick;
10993 }
10994 else if (combolistscrollers[j].rectind(x, y) == 1 && !mouse_down)
10995 {
10996 scrolldown(j);
10997 goto domouse_doneclick;
10998 }
10999 else if (comboaliaslist[j].rect(x, y))
11000 {
11001 select_autocombo(j);
11002
11003 if(rclick && comboaliaslist[j].rect(gui_mouse_x(),gui_mouse_y()))
11004 popup_cpane_rc(x, y);
11005 goto domouse_doneclick;
11006 }
11007 }
11008 }
11009 else
11010 {
11011 for(int32_t j=0; j<num_combo_cols; ++j)
11012 {
11013 if(combolistscrollers[j].rectind(x,y)==0 && !mouse_down)
11014 {
11015 scrollup(j);
11016 goto domouse_doneclick;
11017 }
11018 else if(combolistscrollers[j].rectind(x,y)==1 && !mouse_down)
11019 {
11020 scrolldown(j);
11021 goto domouse_doneclick;
11022 }
11023 else if(combolist[j].rect(x,y))
11024 {
11025 select_combo(j);
11026
11027 if(rclick && combolist[j].rect(gui_mouse_x(),gui_mouse_y()))
11028 popup_cpane_rc(x, y);
11029 goto domouse_doneclick;
11030 }
11031 }
11032 }
11033
11034 //on the favorites list
11035 if(favorites_list.rect(x,y))
11036 {
11037 if(lclick)
11038 {
11039 int32_t f=favorites_list.rectind(x,y);
11040 int32_t row=f/favorites_list.w;
11041 int32_t col=f%favorites_list.w;
11042 f = (row*FAVORITECOMBO_PER_ROW)+col;
11043 int32_t fp = f + FAVORITECOMBO_PER_PAGE * FavoriteComboPage;
11044
11045 bool dmcond = favorite_combos[fp] < 0;
11046 if((key[KEY_LSHIFT] || key[KEY_RSHIFT] || dmcond) && !(CHECK_CTRL_CMD))
11047 {
11048 int32_t tempcb=ComboBrush;
11049 ComboBrush=0;
11050
11051 while(gui_mouse_b())
11052 {
11053 x=gui_mouse_x();
11054 y=gui_mouse_y();
11055
11056 switch(draw_mode)
11057 {
11058 case dm_alias:
11059 if (favorite_combos[fp] != combo_apos || favorite_combo_modes[fp] != dm_alias)
11060 {
11061 favorite_combo_modes[fp] = dm_alias;
11062 favorite_combos[fp] = combo_apos;
11063 mark_save_dirty();
11064 }
11065 break;
11066 case dm_cpool:
11067 if (favorite_combos[fp] != combo_pool_pos || favorite_combo_modes[fp] != dm_cpool)
11068 {
11069 favorite_combo_modes[fp] = dm_cpool;
11070 favorite_combos[fp] = combo_pool_pos;
11071 mark_save_dirty();
11072 }
11073 break;
11074 case dm_auto:
11075 if (favorite_combos[fp] != combo_auto_pos || favorite_combo_modes[fp] != dm_auto)
11076 {
11077 favorite_combo_modes[fp] = dm_auto;
11078 favorite_combos[fp] = combo_auto_pos;
11079 mark_save_dirty();
11080 }
11081 break;
11082 default:
11083 if (favorite_combos[fp] != Combo || favorite_combo_modes[fp] != dm_normal)
11084 {
11085 if (BrushWidth > 1 || BrushHeight > 1)
11086 {
11087 add_favorite_combo_block(f, Combo, key[KEY_LSHIFT] || key[KEY_RSHIFT]);
11088 break;
11089 }
11090 favorite_combo_modes[fp] = dm_normal;
11091 favorite_combos[fp] = Combo;
11092 mark_save_dirty();
11093 }
11094 }
11095
11096 custom_vsync();
11097 refresh(rALL | rFAVORITES);
11098 }
11099
11100 ComboBrush=tempcb;
11101 }
11102 else if(CHECK_CTRL_CMD)
11103 {
11104 int32_t tempcb=ComboBrush;
11105 ComboBrush=0;
11106
11107 while(gui_mouse_b())
11108 {
11109 x=gui_mouse_x();
11110 y=gui_mouse_y();
11111
11112 if(favorite_combos[fp]!=-1)
11113 {
11114 favorite_combo_modes[fp] = dm_normal;
11115 favorite_combos[fp]=-1;
11116 mark_save_dirty();
11117 }
11118
11119 custom_vsync();
11120 refresh(rALL | rFAVORITES);
11121 }
11122
11123 ComboBrush=tempcb;
11124 }
11125 else if(key[KEY_ALT] || key[KEY_ALTGR])
11126 {
11127 if(select_favorite())
11128 {
11129 switch(favorite_combo_modes[fp])
11130 {
11131 case dm_alias:
11132 combo_alistpos[current_comboalist]=scrollto_alias(combo_apos);
11133 break;
11134 case dm_cpool:
11135 combo_pool_listpos[current_cpoollist] = scrollto_cpool(combo_pool_pos);
11136 break;
11137 case dm_auto:
11138 combo_auto_listpos[current_cautolist] = scrollto_cauto(combo_auto_pos);
11139 break;
11140 default:
11141 First[current_combolist]=scrollto_cmb(Combo);
11142 }
11143 }
11144 }
11145 else
11146 {
11147 select_favorite();
11148 }
11149 }
11150 else if(rclick)
11151 {
11152 bool valid=select_favorite();
11153
11154 if(valid)
11155 {
11156 int f = favorites_list.rectind(x,y);
11157 int row = f/favorites_list.w;
11158 int col = f%favorites_list.w;
11159 f = (row*FAVORITECOMBO_PER_ROW) + col + (FAVORITECOMBO_PER_PAGE * FavoriteComboPage);
11160 popup_favorites_rc(f, x, y);
11161 }
11162 }
11163 goto domouse_doneclick;
11164 }
11165
11166 //on the commands buttons
11167 int32_t cmd = commands_list.rectind(x,y);
11168 if(cmd > -1)
11169 {
11170 uint hkey = favorite_commands[cmd];
11171 bool shift=(key[KEY_LSHIFT] || key[KEY_RSHIFT]);
11172 bool ctrl=(CHECK_CTRL_CMD);
11173 bool alt=(key[KEY_ALT] || key[KEY_ALTGR]);
11174 bool dis = disabled_hotkey(hkey);
11175 auto& btn = commands_list.subsquare(cmd);
11176 if(!dis||rclick||shift||ctrl||alt)
11177 {
11178 FONT *tfont=font;
11179 font=get_custom_font(CFONT_FAVCMD);
11180 if(do_layer_button_reset(btn.x,btn.y,btn.w,btn.h,
11181 get_hotkey_name(hkey),
11182 selected_hotkey(hkey)?D_SELECTED:0,
11183 true))
11184 {
11185 font=tfont;
11186 if(alt)
11187 {
11188 show_hotkey_info(hkey);
11189 }
11190 else if(ctrl)
11191 {
11192 write_fav_command(cmd,0);
11193 }
11194 else if(rclick || shift || hkey==ZQKEY_NULL_KEY)
11195 {
11196 if(auto newkey = select_fav_command())
11197 write_fav_command(cmd,*newkey);
11198 }
11199 else
11200 {
11201 run_hotkey(hkey);
11202 }
11203 }
11204
11205 font=tfont;
11206 }
11207 goto domouse_doneclick;
11208 }
11209 }
11210
11211 domouse_doneclick:
11212 mouse_down |= mb&3;
11213
11214 if(mouse_z!=0)
11215 {
11216 int32_t z=0;
11217
11218 for(int32_t j=0; j<num_combo_cols; ++j)
11219 {
11220 z=abs(mouse_z);
11221
11222 if(key[KEY_ALT]||key[KEY_ALTGR])
11223 {
11224 z*=combolist[j].h;
11225 }
11226
11227
11228 if(draw_mode == dm_alias)
11229 {
11230 if(comboaliaslist[j].rect(x,y))
11231 {
11232 if(mouse_z<0) //scroll down
11233 {
11234 combo_alistpos[current_comboalist] = zc_min(MAXCOMBOALIASES - comboaliaslist[j].w*comboaliaslist[j].h,
11235 combo_alistpos[current_comboalist]+comboaliaslist[j].w*z);
11236 }
11237 else //scroll up
11238 {
11239 if(combo_alistpos[current_comboalist]>0)
11240 {
11241 combo_alistpos[current_comboalist]-=zc_min(combo_alistpos[current_comboalist],comboaliaslist[j].w*z);
11242 }
11243 }
11244 goto domouse_donez;
11245 }
11246 }
11247 else if(draw_mode == dm_cpool)
11248 {
11249 if(comboaliaslist[j].rect(x,y))
11250 {
11251 if(mouse_z<0) //scroll down
11252 {
11253 combo_pool_listpos[current_cpoollist] = zc_min(MAXCOMBOPOOLS - comboaliaslist[j].w*comboaliaslist[j].h,
11254 combo_pool_listpos[current_cpoollist]+comboaliaslist[j].w*z);
11255 }
11256 else //scroll up
11257 {
11258 if(combo_pool_listpos[current_cpoollist]>0)
11259 {
11260 combo_pool_listpos[current_cpoollist]-=zc_min(combo_pool_listpos[current_cpoollist],comboaliaslist[j].w*z);
11261 }
11262 }
11263 goto domouse_donez;
11264 }
11265 }
11266 else if (draw_mode == dm_auto)
11267 {
11268 if (comboaliaslist[j].rect(x, y))
11269 {
11270 if (mouse_z < 0) //scroll down
11271 {
11272 combo_auto_listpos[current_cautolist] = zc_min(MAXAUTOCOMBOS - comboaliaslist[j].w * comboaliaslist[j].h,
11273 combo_auto_listpos[current_cautolist] + comboaliaslist[j].w * z);
11274 }
11275 else //scroll up
11276 {
11277 if (combo_auto_listpos[current_cautolist] > 0)
11278 {
11279 combo_auto_listpos[current_cautolist] -= zc_min(combo_auto_listpos[current_cautolist], comboaliaslist[j].w * z);
11280 }
11281 }
11282 goto domouse_donez;
11283 }
11284 }
11285 else
11286 {
11287 if(combolist[j].rect(x,y))
11288 {
11289 if(mouse_z<0) //scroll down
11290 {
11291 First[current_combolist] = zc_min(MAXCOMBOS-combolist[j].w*combolist[j].h,
11292 First[current_combolist] + combolist[j].w*z);
11293 }
11294 else //scroll up
11295 {
11296 if(First[current_combolist]>0)
11297 {
11298 First[current_combolist]-=zc_min(First[current_combolist],combolist[j].w*z);
11299 }
11300 }
11301 goto domouse_donez;
11302 }
11303 }
11304 }
11305
11306 z=abs(mouse_z);
11307
11308 if(real_mini.rect(x,y))
11309 {
11310 for(int32_t i=0; i<z; ++i)
11311 {
11312 if(mouse_z>0) onIncMap();
11313 else onDecMap();
11314 }
11315 goto domouse_donez;
11316 }
11317
11318 if(is_compact && compact_square_panels
11319 && squares_panel.rect(x,y))
11320 {
11321 cycle_compact_sqr(mouse_z < 0);
11322 goto domouse_donez;
11323 }
11324 domouse_donez:
11325 position_mouse_z(0);
11326 }
11327
11328 // Mouse buttons.
11329 {
11330 ALLEGRO_MOUSE_STATE state;
11331 al_get_mouse_state(&state);
11332
11333 static bool btn_4_was_down;
11334 static bool btn_5_was_down;
11335
11336 bool btn_4_down = al_mouse_button_down(&state, 4);
11337 bool btn_5_down = al_mouse_button_down(&state, 5);
11338
11339 if (btn_4_was_down && !btn_4_down)
11340 Map.GoBack();
11341 else if (btn_5_was_down && !btn_5_down)
11342 Map.GoForward();
11343
11344 btn_4_was_down = btn_4_down;
11345 btn_5_was_down = btn_5_down;
11346 }
11347
11348 font = tfont;
11349 active_visible_screen = nullptr;
11350 }
11351
11352 int32_t d_viewpal_proc(int32_t msg, DIALOG *d, int32_t c)
11353 {
11354 int32_t ret = d_bitmap_proc(msg, d, c);
11355 char* buf = (char*)d->dp2; //buffer to store the color code in
11356 DIALOG* d2 = (DIALOG*)d->dp3; //DIALOG* to update the text proc
11357 if(!buf)
11358 return ret;
11359 switch(msg)
11360 {
11361 case MSG_IDLE:
11362 case MSG_GOTMOUSE:
11363 case MSG_LOSTMOUSE:
11364 break;
11365 default:
11366 return ret;
11367 }
11368 char t[16];
11369 memcpy(t, buf, 16);
11370 int32_t x = gui_mouse_x() - d->x;
11371 int32_t y = gui_mouse_y() - d->y;
11372 if(msg != MSG_LOSTMOUSE && isinRect(x, y, 0, 0, d->w-1, d->h-1))
11373 {
11374 float palscale = 1.5;
11375 for(int32_t i = 0; i<256; ++i)
11376 if(isinRect(x,y,(int32_t)(((i&31)<<3)*palscale),(int32_t)(((i&0xE0)>>2)*palscale), (int32_t)((((i&31)<<3)+7)*palscale),(int32_t)((((i&0xE0)>>2)+7)*palscale)))
11377 {
11378 sprintf(buf, "0x%02X (%03d) ", i, i); //Extra spaces to increase drawn width, so it draws the blank area
11379 break;
11380 }
11381 }
11382 else memset(buf, ' ', 15);
11383 if(strcmp(buf, t) && d2 && d2->proc == jwin_text_proc && d2->dp == d->dp2)
11384 object_message(d2, MSG_DRAW, 0);
11385 return ret;
11386 }
11387
11388 static DIALOG showpal_dlg[] =
11389 {
11390 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
11391 { jwin_win_proc, 24, 68, 272, 119, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "View Palette", NULL, NULL },
11392 { jwin_frame_proc, 30, 76+16, 260, 68, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
11393 { d_viewpal_proc, 32, 76+18, 256, 64, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11394 { jwin_text_proc, 32+8,76+18+66, 20, 8, vc(11), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
11395 { jwin_button_proc, 130, 144+18, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
11396 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11397 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
11398 };
11399
11400 int32_t onShowPal()
11401 {
11402 float palscale = 1.5;
11403
11404 BITMAP *palbmp = create_bitmap_ex(8,(int32_t)(256*palscale),(int32_t)(64*palscale));
11405
11406 if(!palbmp)
11407 return D_O_K;
11408 clear_to_color(palbmp,jwin_pal[jcBOX]); //If not cleared, random static appears between swatches! -E
11409 showpal_dlg[0].dp2=get_zc_font(font_lfont);
11410
11411 for(int32_t i=0; i<256; i++)
11412 rectfill(palbmp,(int32_t)(((i&31)<<3)*palscale),(int32_t)(((i&0xE0)>>2)*palscale), (int32_t)((((i&31)<<3)+7)*palscale),(int32_t)((((i&0xE0)>>2)+7)*palscale),i);
11413 showpal_dlg[2].dp=(void *)palbmp;
11414 char buf[16] = {0};
11415 showpal_dlg[2].dp2=(void *)buf;
11416 showpal_dlg[2].dp3=(void *)&(showpal_dlg[3]);
11417 showpal_dlg[3].dp=(void *)buf;
11418 showpal_dlg[3].dp2=(void *)get_zc_font(font_deffont);
11419
11420 large_dialog(showpal_dlg);
11421 do_zqdialog(showpal_dlg,2);
11422 destroy_bitmap(palbmp);
11423 return D_O_K;
11424 }
11425
11426 static DIALOG csetfix_dlg[] =
11427 {
11428 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
11429 { jwin_win_proc, 72, 80, 176+1, 96+1, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "CSet Fix", NULL, NULL },
11430 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11431 { jwin_radio_proc, 104+22, 108, 80+1, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "Full Screen", NULL, NULL },
11432 { jwin_radio_proc, 104+22, 118+2, 80+1, 8+1, vc(14), vc(1), 0, D_SELECTED, 0, 0, (void *) "Dungeon Floor", NULL, NULL },
11433 { d_dummy_proc, 120, 128, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
11434 { jwin_check_proc, 104+22, 128+4, 80+1, 8+1, vc(14), vc(1), 0, 0, 1, 0, (void *) "All Layers", NULL, NULL },
11435 { jwin_button_proc, 90, 152, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
11436 { jwin_button_proc, 170, 152, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
11437 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
11438 };
11439
11440 int32_t onCSetFix()
11441 {
11442 restore_mouse();
11443 csetfix_dlg[0].dp2=get_zc_font(font_lfont);
11444 int32_t s=2,x2=14,y2=9;
11445
11446 large_dialog(csetfix_dlg);
11447
11448 if(do_zqdialog(csetfix_dlg,-1)==6)
11449 {
11450 if(csetfix_dlg[2].flags&D_SELECTED)
11451 {
11452 s=0;
11453 x2=16;
11454 y2=11;
11455 }
11456
11457 if(csetfix_dlg[5].flags&D_SELECTED)
11458 {
11459 /*
11460 int32_t drawmap, drawscr;
11461 if (CurrentLayer==0)
11462 {
11463 drawmap=Map.getCurrMap();
11464 drawscr=Map.getCurrScr();
11465 }
11466 else
11467 {
11468 drawmap=Map.CurrScr()->layermap[CurrentLayer-1]-1;
11469 drawscr=Map.CurrScr()->layerscreen[CurrentLayer-1];
11470 }
11471 mapscr* draw_mapscr = Map.AbsoluteScr(drawmap, drawscr);
11472 if(!draw_mapscr) return;
11473 mark_save_dirty();
11474 Map.Ugo();
11475
11476 if(!(draw_mapscr->valid&mVALID))
11477 {
11478 Map.CurrScr()->valid|=mVALID;
11479 draw_mapscr->valid|=mVALID;
11480 Map.setcolor(Color);
11481 }
11482 for(int32_t i=0; i<176; i++)
11483 {
11484 draw_mapscr->data[i]=Combo;
11485 draw_mapscr->cset[i]=CSet;
11486 }
11487 refresh(rMAP+rSCRMAP);
11488 */
11489 }
11490
11491 Map.StartListCommand();
11492 for(int32_t y=s; y<y2; y++)
11493 {
11494 for(int32_t x=s; x<x2; x++)
11495 {
11496 Map.DoSetComboCommand(Map.getCurrMap(), Map.getCurrScr(), (y<<4)+x, -1, CSet);
11497 }
11498 }
11499 Map.FinishListCommand();
11500
11501 refresh(rMAP);
11502 mark_save_dirty();
11503 }
11504
11505 return D_O_K;
11506 }
11507 static bool doAllSolidWater()
11508 {
11509 for(int32_t i=0; i < MAXCOMBOS; ++i)
11510 {
11511 if(combo_class_buf[combobuf[i].type].water!=0)
11512 {
11513 combobuf[i].walk |= 0x0F; //Solid
11514 }
11515 }
11516 return true;
11517 }
11518 static bool doNoSolidWater()
11519 {
11520 for(int32_t i=0; i < MAXCOMBOS; ++i)
11521 {
11522 if(combo_class_buf[combobuf[i].type].water!=0)
11523 {
11524 combobuf[i].walk &= ~0x0F; //Non-solid
11525 }
11526 }
11527 return true;
11528 }
11529 int32_t onWaterSolidity()
11530 {
11531 AlertFuncDialog("Water Conversion",
11532 "Forcibly set the solidity of all 'Liquid' combos in the quest?",
11533 ""
11534 ).add_buttons(2,
11535 { "Solid", "Non-Solid", "Cancel" },
11536 { doAllSolidWater, doNoSolidWater, nullptr }
11537 ).show();
11538 return D_O_K;
11539 }
11540
11541 static bool doAllEffectSquare()
11542 {
11543 for(int32_t i=0; i < MAXCOMBOS; ++i)
11544 {
11545 combobuf[i].walk |= 0xF0; //Effect
11546 }
11547 return true;
11548 }
11549 static bool doBlankEffectSquare()
11550 {
11551 for(int32_t i=0; i < MAXCOMBOS; ++i)
11552 {
11553 if(combobuf[i].is_blank(true))
11554 {
11555 combobuf[i].walk |= 0xF0; //Effect
11556 }
11557 }
11558 return true;
11559 }
11560
11561 int32_t onEffectFix()
11562 {
11563 AlertFuncDialog("Effect Square Conversion",
11564 "Forcibly fill the green effect square of all combos in the quest?",
11565 ""
11566 ).add_buttons(2,
11567 { "All", "Blank Only", "Cancel" },
11568 { doAllEffectSquare, doBlankEffectSquare, nullptr }
11569 ).show();
11570 return D_O_K;
11571 }
11572
11573 static bool clear_green_arrival_squares()
11574 {
11575 for(mapscr& scr : TheMaps)
11576 {
11577 if(!scr.valid) continue;
11578 scr.warparrivalx = 0;
11579 scr.warparrivaly = 0;
11580 }
11581 set_qr(qr_NOARRIVALPOINT, true);
11582 return true;
11583 }
11584
11585 static bool replace_green_arrival_squares()
11586 {
11587 // Check for conflicts first
11588 bool has_conflicts = false;
11589
11590 for(mapscr& scr : TheMaps)
11591 {
11592 if(!scr.valid) continue;
11593 if(!(scr.warparrivalx || scr.warparrivaly)) continue;
11594 if(scr.warpreturnx[0] || scr.warpreturny[0])
11595 {
11596 has_conflicts = true;
11597 break;
11598 }
11599 }
11600
11601 enum
11602 {
11603 NOT_ASKED = -1,
11604 MODE_FORCE, MODE_IGNORE, MODE_FIND_IGNORE, MODE_FIND_FORCE, MODE_CANCEL
11605 };
11606 int mode = NOT_ASKED;
11607
11608 if(has_conflicts)
11609 {
11610 AlertFuncDialog("Handle Conflicts",
11611 "Warp Square A is not available for all screens that have arrival squares."
11612 " How should this be handled? (See '?' for more info)",
11613 "Overwrite A: Replace the existing warp return square A with the position of the green arrival square"
11614 "\nIgnore: Do nothing if warp return square A exists"
11615 "\nFind Space or Ignore: Choose another, unused, square to set to the position of the green arrival square."
11616 " If none are unused, 'Ignore' instead."
11617 "\nFind Space or Overwrite: Choose another, unused square to set to the position of the green arrival square."
11618 " If none are unused, 'Overwrite A' instead."
11619 "\nCancel: Don't do anything"
11620 ).add_buttons(1,
11621 { "Overwrite A", "Ignore", "Find Space or Ignore", "Find Space or Overwrite A", "Cancel" },
11622 mode
11623 ).show();
11624 if(mode == NOT_ASKED || mode == MODE_CANCEL)
11625 return false;
11626 }
11627 for(mapscr& scr : TheMaps)
11628 {
11629 if(!scr.valid) continue;
11630 if(!(scr.warparrivalx || scr.warparrivaly)) continue;
11631 int indx = 0;
11632 if(scr.warpreturnx[0] || scr.warpreturny[0])
11633 {
11634 if(mode == MODE_IGNORE) continue; // Warp A not free, so ignore
11635 if(mode != MODE_FORCE)
11636 {
11637 for(int q = 1; q < 4; ++q)
11638 {
11639 if(scr.warpreturnx[q] || scr.warpreturny[q])
11640 continue;
11641 indx = q; // Use this warp, since it's free
11642 break;
11643 }
11644 if(indx == 0 && mode == MODE_FIND_IGNORE)
11645 continue; // Nothing free, so ignore
11646 }
11647 }
11648 scr.warpreturnx[indx] = scr.warparrivalx;
11649 scr.warpreturny[indx] = scr.warparrivaly;
11650 scr.warparrivalx = 0;
11651 scr.warparrivaly = 0;
11652 }
11653 set_qr(qr_NOARRIVALPOINT, true);
11654 return true;
11655 }
11656
11657 int32_t onRemoveOldArrivalSquare()
11658 {
11659 AlertFuncDialog("Arrival Square Removal",
11660 "Clear the old green 'Arrival' squares for the whole quest?"
11661 "\n(There will be no further confirmation, and this operation cannot be undone)",
11662 ""
11663 ).add_buttons(2,
11664 { "Replace With Blue Return Square", "Clear Completely", "Cancel" },
11665 { replace_green_arrival_squares, clear_green_arrival_squares, nullptr }
11666 ).show();
11667 return D_O_K;
11668 }
11669
11670 byte* getPalPointer(int32_t pal, int32_t cset)
11671 {
11672 if (pal < 0) return colordata + CSET(cset)*3;
11673 byte* ret = colordata + CSET(pal*pdLEVEL+poLEVEL)*3;
11674 switch(cset)
11675 {
11676 case 2: case 3: case 4:
11677 return ret + CSET(cset-2)*3;
11678 case 9:
11679 return ret + CSET(3)*3;
11680 case 1:
11681 return ret + CSET(13)*3;
11682 case 5:
11683 return ret + CSET(14)*3;
11684 case 7:
11685 return ret + CSET(15)*3;
11686 case 8:
11687 return ret + CSET(16)*3;
11688 }
11689 return NULL;
11690 }
11691
11692 void copyCSet(int32_t destpal, int32_t destcset, int32_t srcpal, int32_t srccset)
11693 {
11694 byte* dest = getPalPointer(destpal, destcset);
11695 byte* src = getPalPointer(srcpal, srccset);
11696 if (dest && src)
11697 {
11698 memcpy(dest, src, 16*3);
11699 }
11700 }
11701
11702 void setColorPalette(int32_t flags, int32_t lowpal, int32_t highpal)
11703 {
11704 for (auto q = lowpal; q <= highpal; ++q)
11705 {
11706 for (auto c = 0; c < 12; ++c)
11707 {
11708 if (!(flags&(1<<c))) continue;
11709 copyCSet(q, c, -1, c);
11710 }
11711 }
11712 }
11713
11714 void setPitDamage(int32_t flags, int32_t lowcombo, int32_t highcombo, int32_t damage)
11715 {
11716 for(int32_t i=lowcombo; i < highcombo; ++i)
11717 {
11718 if((combobuf[i].type == cPITFALL && (flags & (1<<0)))
11719 || (combobuf[i].type == cWATER && !(combobuf[i].usrflags & (1<<0)) && (flags & (1<<1)))
11720 || (combobuf[i].type == cWATER && (combobuf[i].usrflags & (1<<0)) && (flags & (1<<2))))
11721 {
11722 if ((combobuf[i].type != cPITFALL || (flags & (1<<9)) || !(combobuf[i].usrflags & (1<<0)))
11723 && ((flags & (1<<8)) || combobuf[i].c_attributes[0] == 0))
11724 combobuf[i].c_attributes[0] = damage;
11725 }
11726 }
11727 }
11728
11729 static DIALOG template_dlg[] =
11730 {
11731 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
11732 { jwin_win_proc, 72, 80, 176+1, 116+1, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "NES Dungeon Template", NULL, NULL },
11733 { d_comboframe_proc, 178, 122+3, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
11734 { d_combo_proc, 180, 124+3, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11735 // { d_bitmap_proc, 180, 104, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11736 { jwin_radio_proc, 104+33, 128+3, 64+1, 8+1, vc(14), vc(1), 0, D_SELECTED, 0, 0, (void *) "Floor:", NULL, NULL },
11737 { jwin_radio_proc, 104+33, 148+3, 64+1, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "No Floor", NULL, NULL },
11738 { jwin_button_proc, 90, 172, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
11739 { jwin_button_proc, 170, 172, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
11740 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11741 { jwin_text_proc, 104, 102, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "This copies the contents of", NULL, NULL },
11742 { jwin_text_proc, 104, 112, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "screen 83 of the current map.", NULL, NULL },
11743 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
11744 };
11745
11746 int32_t onTemplate()
11747 {
11748 static bool donethis=false;
11749
11750 if(!donethis||!(key[KEY_LSHIFT]||key[KEY_RSHIFT]))
11751 {
11752 template_dlg[2].d1=Combo;
11753 template_dlg[2].fg=CSet;
11754 donethis=true;
11755 }
11756
11757 restore_mouse();
11758
11759 if(Map.getCurrScr()==TEMPLATE)
11760 return D_O_K;
11761
11762 // BITMAP *floor_bmp = create_bitmap_ex(8,16,16);
11763 // if(!floor_bmp) return D_O_K;
11764 template_dlg[0].dp2=get_zc_font(font_lfont);
11765 // put_combo(floor_bmp,0,0,Combo,CSet,0,0);
11766 // template_dlg[2].dp=floor_bmp;
11767
11768 large_dialog(template_dlg);
11769
11770 if(do_zqdialog(template_dlg,-1)==5)
11771 {
11772 mark_save_dirty();
11773 int screen = active_visible_screen ? active_visible_screen->screen : Map.getCurrScr();
11774 Map.DoTemplateCommand((template_dlg[3].flags==D_SELECTED) ? template_dlg[2].d1 : -1, template_dlg[2].fg, screen);
11775 refresh(rMAP+rSCRMAP);
11776 }
11777
11778 // destroy_bitmap(floor_bmp);
11779 return D_O_K;
11780 }
11781
11782 static DIALOG cflag_dlg[] =
11783 {
11784 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
11785 12 { jwin_win_proc, 60-12, 40, 200+24, 148, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
11786 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
11787 12 { jwin_abclist_proc, 72-12-4, 60+4, 176+24+8, 92+3, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, NULL, NULL, NULL },
11788 12 { jwin_button_proc, 70, 163, 51, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
11789 12 { jwin_button_proc, 190, 163, 51, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
11790 12 { jwin_button_proc, 130, 163, 51, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Help", NULL, NULL },
11791 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
11792 };
11793
11794
11795 void questrev_help()
11796 {
11797 displayinfo("Help","The revision number of your quest.");
11798 }
11799
11800 void questminrev_help()
11801 {
11802 displayinfo("Help","If a player's saved game was from a revision less than the minimum revision, they have to restart from the beginning. This is useful if you make major changes to your quest.");
11803 }
11804
11805 int32_t select_cflag(const char *prompt,int32_t flag)
11806 {
11807 cflag_dlg[0].dp=(void *)prompt;
11808 cflag_dlg[0].dp2=get_zc_font(font_lfont);
11809 GUI::ListData ld = GUI::ZCListData::mapflag(numericalFlags, true);
11810 ListData select_cflag_list = ld.getJWin(&font);
11811 auto index = ld.findIndex(flag);
11812 cflag_dlg[2].d1=index.value_or(0);
11813 cflag_dlg[2].dp=(void *) &select_cflag_list;
11814
11815 large_dialog(cflag_dlg);
11816
11817 int32_t ret;
11818
11819 do
11820 {
11821 ret=do_zqdialog(cflag_dlg,2);
11822
11823 if(ret==5)
11824 {
11825 cflag_help(ld.getValue(cflag_dlg[2].d1));
11826 }
11827 }
11828 while(ret==5);
11829
11830 if(ret==0||ret==4)
11831 {
11832 position_mouse_z(0);
11833 return -1;
11834 }
11835
11836 return ld.getValue(cflag_dlg[2].d1);
11837 }
11838
11839 int32_t select_flag(int32_t &f)
11840 {
11841 int32_t ret=select_cflag("Flag Type",f);
11842
11843 if(ret>=0)
11844 {
11845 f=ret;
11846 return true;
11847 }
11848
11849 return false;
11850 }
11851
11852 int32_t d_scombo_proc(int32_t msg,DIALOG *d,int32_t c)
11853 {
11854 //these are here to bypass compiler warnings about unused arguments
11855 c=c;
11856
11857 switch(msg)
11858 {
11859 case MSG_CLICK:
11860 {
11861 int32_t c2=d->d1;
11862 int32_t cs=d->fg;
11863 int32_t f=d->d2;
11864
11865 if(d->bg==1 || (CHECK_CTRL_CMD))
11866 {
11867 while(gui_mouse_b())
11868 {
11869 /* do nothing */
11870 rest(1);
11871 }
11872
11873 if(select_flag(f))
11874 {
11875 d->d2=f;
11876
11877 }
11878 }
11879 else if(key[KEY_LSHIFT])
11880 {
11881 if(gui_mouse_b()&1)
11882 {
11883 d->d1++;
11884
11885 if(d->d1>=MAXCOMBOS) d->d1=0;
11886 }
11887 else if(gui_mouse_b()&2)
11888 {
11889 d->d1--;
11890
11891 if(d->d1<0) d->d1=MAXCOMBOS-1;
11892 }
11893 }
11894 else if(key[KEY_RSHIFT])
11895 {
11896 if(gui_mouse_b()&1)
11897 {
11898 d->fg++;
11899
11900 if(d->fg>11) d->fg=0;
11901 }
11902 else if(gui_mouse_b()&2)
11903 {
11904 d->fg--;
11905
11906 if(d->fg<0) d->fg=11;
11907 }
11908 }
11909 else if(key[KEY_ALT])
11910 {
11911 if(gui_mouse_b()&1)
11912 {
11913 d->d1 = Combo;
11914 d->fg = CSet;
11915 }
11916 }
11917 else
11918 {
11919 if(select_combo_2(c2, cs))
11920 {
11921 d->d1=c2;
11922 d->fg=cs;
11923 }
11924 }
11925
11926 return D_REDRAW;
11927 }
11928 break;
11929
11930 case MSG_DRAW:
11931 d->w = 32;
11932 d->h = 32;
11933
11934 BITMAP *buf = create_bitmap_ex(8,16,16);
11935 BITMAP *bigbmp = create_bitmap_ex(8,d->w,d->h);
11936
11937 if(buf && bigbmp)
11938 {
11939 clear_bitmap(buf);
11940
11941 if(d->bg) //flags only
11942 {
11943 put_flag(buf,0,0,d->d2);
11944 }
11945 else if(d->d1)
11946 {
11947 putcombo(buf,0,0,d->d1,d->fg);
11948
11949 if(Flags&cFLAGS)
11950 put_flags(buf,0,0,d->d1,d->fg,cFLAGS,d->d2);
11951 }
11952
11953 stretch_blit(buf, bigbmp, 0,0, 16, 16, 0, 0, d->w, d->h);
11954 destroy_bitmap(buf);
11955 blit(bigbmp,screen,0,0,d->x-1,d->y-1,d->w,d->h);
11956 destroy_bitmap(bigbmp);
11957 }
11958
11959
11960 /*BITMAP *buf = create_bitmap_ex(8,16,16);
11961 if(buf)
11962 {
11963 clear_bitmap(buf);
11964 if(d->d1)
11965 putcombo(buf,0,0,d->d1,d->fg);
11966
11967 blit(buf,screen,0,0,d->x,d->y,d->w,d->h);
11968 destroy_bitmap(buf);
11969 }*/
11970 break;
11971 }
11972
11973 return D_O_K;
11974 }
11975
11976 int32_t onSecretF();
11977
11978 static int32_t secret_burn_list[] =
11979 {
11980 // dialog control number
11981 4, 5, 6, 7, 48, 49, 50, 51, 92, 93, 94, 95, -1
11982 };
11983
11984 static int32_t secret_arrow_list[] =
11985 {
11986 // dialog control number
11987 8, 9, 10, 52, 53, 54, 96, 97, 98, -1
11988 };
11989
11990 static int32_t secret_bomb_list[] =
11991 {
11992 // dialog control number
11993 11, 12, 55, 56, 99, 100, -1
11994 };
11995
11996 static int32_t secret_boomerang_list[] =
11997 {
11998 // dialog control number
11999 13, 14, 15, 57, 58, 59, 101, 102, 103, -1
12000 };
12001
12002 static int32_t secret_magic_list[] =
12003 {
12004 // dialog control number
12005 16, 17, 60, 61, 104, 105, -1
12006 };
12007
12008 static int32_t secret_sword_list[] =
12009 {
12010 // dialog control number
12011 18, 19, 20, 21, 22, 23, 24, 25, 62, 63, 64, 65, 66, 67, 68, 69, 106, 107, 108, 109, 110, 111, 112, 113, -1
12012 };
12013
12014 static int32_t secret_misc_list[] =
12015 {
12016 // dialog control number
12017 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, -1
12018 };
12019
12020 static TABPANEL secret_tabs[] =
12021 {
12022 // (text)
12023 { (char *)"Burn", D_SELECTED, secret_burn_list, 0, NULL },
12024 { (char *)"Arrow", 0, secret_arrow_list, 0, NULL },
12025 { (char *)"Bomb", 0, secret_bomb_list, 0, NULL },
12026 { (char *)"Boomerang", 0, secret_boomerang_list, 0, NULL },
12027 { (char *)"Magic", 0, secret_magic_list, 0, NULL },
12028 { (char *)"Sword", 0, secret_sword_list, 0, NULL },
12029 { (char *)"Misc", 0, secret_misc_list, 0, NULL },
12030 { NULL, 0, NULL, 0, NULL }
12031 };
12032
12033 static DIALOG secret_dlg[] =
12034 {
12035 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) (dp2) (dp3)
12036 { jwin_win_proc, 0, 0, 301, 212, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
12037 { jwin_tab_proc, 6, 25, 289, 156, 0, 0, 0, 0, 0, 0, (void *) secret_tabs, NULL, (void *)secret_dlg },
12038 { jwin_button_proc, 80, 187, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
12039 { jwin_button_proc, 160, 187, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
12040 // 4
12041 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Any Fire", NULL, NULL },
12042 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Strong Fire", NULL, NULL },
12043 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Magic Fire", NULL, NULL },
12044 { jwin_text_proc, 12, 119, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Divine Fire", NULL, NULL },
12045 //8
12046 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Wooden Arrow", NULL, NULL },
12047 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Silver Arrow", NULL, NULL },
12048 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Golden Arrow", NULL, NULL },
12049 //11
12050 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Bomb", NULL, NULL },
12051 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Super Bomb", NULL, NULL },
12052 //13
12053 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Wooden Boomerang", NULL, NULL },
12054 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Magic Boomerang", NULL, NULL },
12055 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Fire Boomerang", NULL, NULL },
12056 //16
12057 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Wand Magic", NULL, NULL },
12058 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Reflected Magic", NULL, NULL },
12059 //18
12060 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Sword", NULL, NULL },
12061 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "White Sword", NULL, NULL },
12062 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Magic Sword", NULL, NULL },
12063 { jwin_text_proc, 12, 119, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Master Sword", NULL, NULL },
12064 { jwin_text_proc, 160, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Sword Beam", NULL, NULL },
12065 { jwin_text_proc, 160, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "White Sword Beam", NULL, NULL },
12066 { jwin_text_proc, 160, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Magic Sword Beam", NULL, NULL },
12067 { jwin_text_proc, 160, 119, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Master Sword Beam", NULL, NULL },
12068 //26
12069 { jwin_text_proc, 12, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Stairs", NULL, NULL },
12070 { jwin_text_proc, 12, 75, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Reflected Fireball", NULL, NULL },
12071 { jwin_text_proc, 12, 97, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Hookshot", NULL, NULL },
12072 { jwin_text_proc, 12, 119, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Wand", NULL, NULL },
12073 { jwin_text_proc, 12, 141, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Hammer", NULL, NULL },
12074 { jwin_text_proc, 12, 163, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Any Weapon", NULL, NULL },
12075 //32
12076 { jwin_ctext_proc, 235, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Flags 16-31", NULL, NULL },
12077 { jwin_text_proc, 87, 53, 16, 16, vc(11), vc(1), 0, 0, 0, 0, (void *) "Secrets->Next (Flag only)", NULL, NULL },
12078 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 03", NULL, NULL },
12079 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 04", NULL, NULL },
12080 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 05", NULL, NULL },
12081 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 06", NULL, NULL },
12082 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 07", NULL, NULL },
12083 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 08", NULL, NULL },
12084 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 09", NULL, NULL },
12085 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 10", NULL, NULL },
12086 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 11", NULL, NULL },
12087 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 12", NULL, NULL },
12088 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 13", NULL, NULL },
12089 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 14", NULL, NULL },
12090 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 15", NULL, NULL },
12091 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, FR_DEEP, 0, (void *) "Secret Combo 16", NULL, NULL },
12092 //48 (burn)
12093 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12094 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12095 { jwin_frame_proc, 108, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12096 { jwin_frame_proc, 108, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12097 //52 (arrow)
12098 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12099 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12100 { jwin_frame_proc, 108, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12101 //55 (bomb)
12102 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12103 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12104 //57 (boomerang)
12105 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12106 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12107 { jwin_frame_proc, 108, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12108 //60 (magic)
12109 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12110 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12111 //62 (sword)
12112 { jwin_frame_proc, 108, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12113 { jwin_frame_proc, 108, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12114 { jwin_frame_proc, 108, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12115 { jwin_frame_proc, 108, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12116 { jwin_frame_proc, 256, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12117 { jwin_frame_proc, 256, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12118 { jwin_frame_proc, 256, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12119 { jwin_frame_proc, 256, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12120 //70 (misc)
12121 { jwin_frame_proc, 63, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12122 { jwin_frame_proc, 63, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12123 { jwin_frame_proc, 63, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12124 { jwin_frame_proc, 63, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12125 { jwin_frame_proc, 63, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12126 { jwin_frame_proc, 63, 157, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12127 //76 (16-32)
12128 { jwin_frame_proc, 192, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12129 { jwin_frame_proc, 214, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12130 { jwin_frame_proc, 236, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12131 { jwin_frame_proc, 258, 69, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12132 { jwin_frame_proc, 192, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12133 { jwin_frame_proc, 214, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12134 { jwin_frame_proc, 236, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12135 { jwin_frame_proc, 258, 91, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12136 { jwin_frame_proc, 192, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12137 { jwin_frame_proc, 214, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12138 { jwin_frame_proc, 236, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12139 { jwin_frame_proc, 258, 113, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12140 { jwin_frame_proc, 192, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12141 { jwin_frame_proc, 214, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12142 { jwin_frame_proc, 236, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12143 { jwin_frame_proc, 258, 135, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12144
12145 //92 (burn)
12146 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12147 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12148 { d_scombo_proc, 110, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12149 { d_scombo_proc, 110, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12150 //96 (arrow)
12151 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12152 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12153 { d_scombo_proc, 110, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12154 //99 (bomb)
12155 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12156 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12157 //101 (boomerang)
12158 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12159 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12160 { d_scombo_proc, 110, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12161 //104 (magic)
12162 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12163 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12164 //106 (sword)
12165 { d_scombo_proc, 110, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12166 { d_scombo_proc, 110, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12167 { d_scombo_proc, 110, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12168 { d_scombo_proc, 110, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12169 { d_scombo_proc, 258, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12170 { d_scombo_proc, 258, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12171 { d_scombo_proc, 258, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12172 { d_scombo_proc, 258, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12173 //114 (misc)
12174 { d_scombo_proc, 65, 49, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12175 { d_scombo_proc, 65, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12176 { d_scombo_proc, 65, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12177 { d_scombo_proc, 65, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12178 { d_scombo_proc, 65, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12179 { d_scombo_proc, 65, 159, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12180 //120 (16-32)
12181 { d_scombo_proc, 194, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12182 { d_scombo_proc, 216, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12183 { d_scombo_proc, 238, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12184 { d_scombo_proc, 260, 71, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12185 { d_scombo_proc, 194, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12186 { d_scombo_proc, 216, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12187 { d_scombo_proc, 238, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12188 { d_scombo_proc, 260, 93, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12189 { d_scombo_proc, 194, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12190 { d_scombo_proc, 216, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12191 { d_scombo_proc, 238, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12192 { d_scombo_proc, 260, 115, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12193 { d_scombo_proc, 194, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12194 { d_scombo_proc, 216, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12195 { d_scombo_proc, 238, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12196 { d_scombo_proc, 260, 137, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12197 //136 Secrets->Next
12198 { jwin_frame_proc, 158, 47, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
12199 { d_scombo_proc, 160, 49, 16, 16, 0, 1, 0, 0, 0, 0, NULL, NULL, NULL },
12200 //138
12201 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *) onHelp, NULL, NULL },
12202 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 'f', 0, 0, 0, (void *) onSecretF, NULL, NULL },
12203 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12204 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
12205 };
12206
12207 int32_t onSecretF()
12208 {
12209 Flags^=cFLAGS;
12210 object_message(secret_dlg+1, MSG_DRAW, 0);
12211 return D_O_K;
12212 }
12213
12214
12215 int32_t onSecretCombo()
12216 {
12217 secret_dlg[0].dp2=get_zc_font(font_lfont);
12218
12219
12220 mapscr *s;
12221
12222 if(CurrentLayer==0)
12223 {
12224 s=Map.CurrScr();
12225 }
12226 else
12227 {
12228 // s=TheMaps[(Map.CurrScr()->layermap[CurrentLayer-1]-1)*MAPSCRS+(Map.CurrScr()->layerscreen[CurrentLayer-1])];
12229 s=Map.AbsoluteScr((Map.CurrScr()->layermap[CurrentLayer-1]-1), (Map.CurrScr()->layerscreen[CurrentLayer-1]));
12230 }
12231 if(!s) return D_O_K;
12232
12233 char secretcombonumstr[27];
12234 sprintf(secretcombonumstr,"Secret Combos for Layer %d", CurrentLayer);
12235 secret_dlg[0].dp = secretcombonumstr;
12236
12237 secret_dlg[92].d1 = s->secretcombo[sBCANDLE];
12238 secret_dlg[92].fg = s->secretcset[sBCANDLE];
12239 secret_dlg[92].d2 = s->secretflag[sBCANDLE];
12240
12241 secret_dlg[93].d1 = s->secretcombo[sRCANDLE];
12242 secret_dlg[93].fg = s->secretcset[sRCANDLE];
12243 secret_dlg[93].d2 = s->secretflag[sRCANDLE];
12244
12245 secret_dlg[94].d1 = s->secretcombo[sWANDFIRE];
12246 secret_dlg[94].fg = s->secretcset[sWANDFIRE];
12247 secret_dlg[94].d2 = s->secretflag[sWANDFIRE];
12248
12249 secret_dlg[95].d1 = s->secretcombo[sDIVINEFIRE];
12250 secret_dlg[95].fg = s->secretcset[sDIVINEFIRE];
12251 secret_dlg[95].d2 = s->secretflag[sDIVINEFIRE];
12252
12253 secret_dlg[96].d1 = s->secretcombo[sARROW];
12254 secret_dlg[96].fg = s->secretcset[sARROW];
12255 secret_dlg[96].d2 = s->secretflag[sARROW];
12256
12257 secret_dlg[97].d1 = s->secretcombo[sSARROW];
12258 secret_dlg[97].fg = s->secretcset[sSARROW];
12259 secret_dlg[97].d2 = s->secretflag[sSARROW];
12260
12261 secret_dlg[98].d1 = s->secretcombo[sGARROW];
12262 secret_dlg[98].fg = s->secretcset[sGARROW];
12263 secret_dlg[98].d2 = s->secretflag[sGARROW];
12264
12265 secret_dlg[99].d1 = s->secretcombo[sBOMB];
12266 secret_dlg[99].fg = s->secretcset[sBOMB];
12267 secret_dlg[99].d2 = s->secretflag[sBOMB];
12268
12269 secret_dlg[100].d1 = s->secretcombo[sSBOMB];
12270 secret_dlg[100].fg = s->secretcset[sSBOMB];
12271 secret_dlg[100].d2 = s->secretflag[sSBOMB];
12272
12273 for(int32_t i=0; i<3; i++)
12274 {
12275 secret_dlg[101+i].d1 = s->secretcombo[sBRANG+i];
12276 secret_dlg[101+i].fg = s->secretcset[sBRANG+i];
12277 secret_dlg[101+i].d2 = s->secretflag[sBRANG+i];
12278 }
12279
12280 for(int32_t i=0; i<2; i++)
12281 {
12282 secret_dlg[104+i].d1 = s->secretcombo[sWANDMAGIC+i];
12283 secret_dlg[104+i].fg = s->secretcset[sWANDMAGIC+i];
12284 secret_dlg[104+i].d2 = s->secretflag[sWANDMAGIC+i];
12285 }
12286
12287 for(int32_t i=0; i<8; i++)
12288 {
12289 secret_dlg[106+i].d1 = s->secretcombo[sSWORD+i];
12290 secret_dlg[106+i].fg = s->secretcset[sSWORD+i];
12291 secret_dlg[106+i].d2 = s->secretflag[sSWORD+i];
12292 }
12293
12294 secret_dlg[114].d1 = s->secretcombo[sSTAIRS];
12295 secret_dlg[114].fg = s->secretcset[sSTAIRS];
12296 secret_dlg[114].d2 = s->secretflag[sSTAIRS];
12297
12298 secret_dlg[115].d1 = s->secretcombo[sREFFIREBALL];
12299 secret_dlg[115].fg = s->secretcset[sREFFIREBALL];
12300 secret_dlg[115].d2 = s->secretflag[sREFFIREBALL];
12301
12302 for(int32_t i=0; i<4; i++)
12303 {
12304 secret_dlg[116+i].d1 = s->secretcombo[sHOOKSHOT+i];
12305 secret_dlg[116+i].fg = s->secretcset[sHOOKSHOT+i];
12306 secret_dlg[116+i].d2 = s->secretflag[sHOOKSHOT+i];
12307 }
12308
12309 for(int32_t i=0; i<16; i++)
12310 {
12311 secret_dlg[120+i].d1 = s->secretcombo[sSECRET01+i];
12312 secret_dlg[120+i].fg = s->secretcset[sSECRET01+i];
12313 secret_dlg[120+i].d2 = s->secretflag[sSECRET01+i];
12314 }
12315
12316 //Sec->Next doesn't have a combo/cset value associated
12317 secret_dlg[137].d1 = 0;
12318 secret_dlg[137].fg = 0;
12319 secret_dlg[137].d2 = s->secretflag[sSECNEXT];
12320
12321 large_dialog(secret_dlg,1.75);
12322
12323 for(int32_t q = 0; secret_dlg[q].proc != NULL; ++q)
12324 {
12325 if(secret_dlg[q].proc == jwin_frame_proc)
12326 secret_dlg[q].w = secret_dlg[q].h = 36;
12327 }
12328
12329 if(do_zqdialog(secret_dlg,3) == 2)
12330 {
12331 mark_save_dirty();
12332 s->secretcombo[sBCANDLE] = secret_dlg[92].d1;
12333 s->secretcset[sBCANDLE] = secret_dlg[92].fg;
12334 s->secretflag[sBCANDLE] = secret_dlg[92].d2;
12335
12336 s->secretcombo[sRCANDLE] = secret_dlg[93].d1;
12337 s->secretcset[sRCANDLE] = secret_dlg[93].fg;
12338 s->secretflag[sRCANDLE] = secret_dlg[93].d2;
12339
12340 s->secretcombo[sWANDFIRE] = secret_dlg[94].d1;
12341 s->secretcset[sWANDFIRE] = secret_dlg[94].fg;
12342 s->secretflag[sWANDFIRE] = secret_dlg[94].d2;
12343
12344 s->secretcombo[sDIVINEFIRE] = secret_dlg[95].d1;
12345 s->secretcset[sDIVINEFIRE] = secret_dlg[95].fg;
12346 s->secretflag[sDIVINEFIRE] = secret_dlg[95].d2;
12347
12348 s->secretcombo[sARROW] = secret_dlg[96].d1;
12349 s->secretcset[sARROW] = secret_dlg[96].fg;
12350 s->secretflag[sARROW] = secret_dlg[96].d2;
12351
12352 s->secretcombo[sSARROW] = secret_dlg[97].d1;
12353 s->secretcset[sSARROW] = secret_dlg[97].fg;
12354 s->secretflag[sSARROW] = secret_dlg[97].d2;
12355
12356 s->secretcombo[sGARROW] = secret_dlg[98].d1;
12357 s->secretcset[sGARROW] = secret_dlg[98].fg;
12358 s->secretflag[sGARROW] = secret_dlg[98].d2;
12359
12360 s->secretcombo[sBOMB] = secret_dlg[99].d1;
12361 s->secretcset[sBOMB] = secret_dlg[99].fg;
12362 s->secretflag[sBOMB] = secret_dlg[99].d2;
12363
12364 s->secretcombo[sSBOMB] = secret_dlg[100].d1;
12365 s->secretcset[sSBOMB] = secret_dlg[100].fg;
12366 s->secretflag[sSBOMB] = secret_dlg[100].d2;
12367
12368 for(int32_t i=0; i<3; i++)
12369 {
12370 s->secretcombo[sBRANG+i] = secret_dlg[101+i].d1;
12371 s->secretcset[sBRANG+i] = secret_dlg[101+i].fg;
12372 s->secretflag[sBRANG+i] = secret_dlg[101+i].d2;
12373 }
12374
12375 for(int32_t i=0; i<2; i++)
12376 {
12377 s->secretcombo[sWANDMAGIC+i] = secret_dlg[104+i].d1;
12378 s->secretcset[sWANDMAGIC+i] = secret_dlg[104+i].fg;
12379 s->secretflag[sWANDMAGIC+i] = secret_dlg[104+i].d2;
12380 }
12381
12382 for(int32_t i=0; i<8; i++)
12383 {
12384 s->secretcombo[sSWORD+i] = secret_dlg[106+i].d1;
12385 s->secretcset[sSWORD+i] = secret_dlg[106+i].fg;
12386 s->secretflag[sSWORD+i] = secret_dlg[106+i].d2;
12387 }
12388
12389 s->secretcombo[sSTAIRS] = secret_dlg[114].d1;
12390 s->secretcset[sSTAIRS] = secret_dlg[114].fg;
12391 s->secretflag[sSTAIRS] = secret_dlg[114].d2;
12392
12393 s->secretcombo[sREFFIREBALL] = secret_dlg[115].d1;
12394 s->secretcset[sREFFIREBALL] = secret_dlg[115].fg;
12395 s->secretflag[sREFFIREBALL] = secret_dlg[115].d2;
12396
12397 for(int32_t i=0; i<4; i++)
12398 {
12399 s->secretcombo[sHOOKSHOT+i] = secret_dlg[116+i].d1;
12400 s->secretcset[sHOOKSHOT+i] = secret_dlg[116+i].fg;
12401 s->secretflag[sHOOKSHOT+i] = secret_dlg[116+i].d2;
12402 }
12403
12404 for(int32_t i=0; i<16; i++)
12405 {
12406 s->secretcombo[sSECRET01+i] = secret_dlg[120+i].d1;
12407 s->secretcset[sSECRET01+i] = secret_dlg[120+i].fg;
12408 s->secretflag[sSECRET01+i] = secret_dlg[120+i].d2;
12409 }
12410 s->secretflag[sSECNEXT] = secret_dlg[137].d2;
12411
12412 }
12413
12414 return D_O_K;
12415 }
12416
12417 void call_undercombo_dlg(int map, int screen);
12418 int32_t onUnderCombo()
12419 {
12420 call_undercombo_dlg(Map.getCurrMap(), Map.getCurrScr());
12421 return D_O_K;
12422 }
12423
12424 static DIALOG list_dlg[] =
12425 {
12426 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
12427 12 { jwin_win_proc, 60-12, 40, 200+24, 148, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
12428 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12429 12 { jwin_list_proc, 72-12-4, 60+4, 176+24+8, 92+3, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, NULL, NULL, NULL },
12430 12 { jwin_button_proc, 90, 163, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
12431 12 { jwin_button_proc, 170, 163, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
12432 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
12433 };
12434
12435 /*
12436 typedef struct item_struct {
12437 char *s;
12438 int32_t i;
12439 } item_struct;
12440 */
12441 item_struct bii[MAXITEMS+1];
12442 int32_t bii_cnt=-1;
12443
12444 void build_bii_list(bool usenone)
12445 {
12446 int32_t start=bii_cnt=0;
12447
12448 if(usenone)
12449 {
12450 bii[0].s = (char *)"(None)";
12451 bii[0].i = -2;
12452 bii_cnt=start=1;
12453 }
12454
12455 for(int32_t i=0; i<MAXITEMS; i++)
12456 {
12457 bii[bii_cnt].s = item_string[i];
12458 bii[bii_cnt].i = i;
12459 ++bii_cnt;
12460 }
12461
12462 for(int32_t i=start; i<bii_cnt-1; i++)
12463 {
12464 for(int32_t j=i+1; j<bii_cnt; j++)
12465 {
12466 if(stricmp(bii[i].s,bii[j].s)>0 && strcmp(bii[j].s,""))
12467 {
12468 zc_swap(bii[i],bii[j]);
12469 }
12470 }
12471 }
12472 }
12473
12474 const char *itemlist_num(int32_t index, int32_t *list_size)
12475 {
12476 if(index<0)
12477 {
12478 *list_size = bii_cnt;
12479 return NULL;
12480 }
12481 static char biin_buf[64+6];
12482 if(bii[index].i < 0)
12483 return bii[index].s;
12484 sprintf(biin_buf, "%s (%03d)", bii[index].s, bii[index].i);
12485 return biin_buf;
12486 }
12487
12488 weapon_struct biw[MAXWPNS];
12489 int32_t biw_cnt=-1;
12490
12491 void build_biw_list()
12492 {
12493 int32_t start=biw_cnt=0;
12494
12495 for(int32_t i=start; i<MAXWPNS; i++)
12496 {
12497 biw[biw_cnt].s = (char *)weapon_string[i];
12498 biw[biw_cnt].i = i;
12499 ++biw_cnt;
12500 }
12501
12502 for(int32_t i=start; i<biw_cnt-1; i++)
12503 {
12504 for(int32_t j=i+1; j<biw_cnt; j++)
12505 if(stricmp(biw[i].s,biw[j].s)>0 && strcmp(biw[j].s,""))
12506 zc_swap(biw[i],biw[j]);
12507 }
12508 }
12509
12510 int32_t writeoneweapon(PACKFILE *f, int32_t index)
12511 {
12512 dword section_version=V_WEAPONS;
12513 int32_t zversion = ZELDA_VERSION;
12514 int32_t zbuild = VERSION_BUILD;
12515 int32_t iid = biw[index].i;
12516 al_trace("Writing Weapon Sprite .zwpnspr file for weapon id: %d\n", iid);
12517
12518 //section version info
12519 if(!p_iputl(zversion,f))
12520 {
12521 return 0;
12522 }
12523 if(!p_iputl(zbuild,f))
12524 {
12525 return 0;
12526 }
12527 if(!p_iputw(section_version,f))
12528 {
12529 return 0;
12530 }
12531
12532 if(!write_deprecated_section_cversion(section_version, f))
12533 {
12534 return 0;
12535 }
12536
12537 //weapon string
12538
12539 if(!pfwrite((char *)weapon_string[iid], 64, f))
12540 {
12541 return 0;
12542 }
12543
12544 if(!p_putc(wpnsbuf[iid].misc,f))
12545 {
12546 return 0;
12547 }
12548
12549 if(!p_putc(wpnsbuf[iid].csets,f))
12550 {
12551 return 0;
12552 }
12553
12554 if(!p_putc(wpnsbuf[iid].frames,f))
12555 {
12556 return 0;
12557 }
12558
12559 if(!p_putc(wpnsbuf[iid].speed,f))
12560 {
12561 return 0;
12562 }
12563
12564 if(!p_putc(wpnsbuf[iid].type,f))
12565 {
12566 return 0;
12567 }
12568
12569 if(!p_iputw(wpnsbuf[iid].script,f))
12570 {
12571 return 0;
12572 }
12573
12574 //2.55 starts here
12575 if(!p_iputl(wpnsbuf[iid].tile,f))
12576 {
12577 return 0;
12578 }
12579
12580 return 1;
12581 }
12582
12583
12584 int32_t readoneweapon(PACKFILE *f, int32_t index)
12585 {
12586 dword section_version = 0;
12587 int32_t zversion = 0;
12588 int32_t zbuild = 0;
12589 wpndata tempwpnspr;
12590 memset(&tempwpnspr, 0, sizeof(wpndata));
12591
12592
12593 //char dmapstring[64]={0};
12594 //section version info
12595 if(!p_igetl(&zversion,f))
12596 {
12597 return 0;
12598 }
12599 if(!p_igetl(&zbuild,f))
12600 {
12601 return 0;
12602 }
12603 if(!p_igetw(&section_version,f))
12604 {
12605 return 0;
12606 }
12607 if(!read_deprecated_section_cversion(f))
12608 {
12609 return 0;
12610 }
12611 al_trace("readoneweapon section_version: %d\n", section_version);
12612
12613 if ( zversion > ZELDA_VERSION )
12614 {
12615 al_trace("Cannot read .zwpnspr packfile made in ZC version (%x) in this version of ZC (%x)\n", zversion, ZELDA_VERSION);
12616 return 0;
12617 }
12618
12619 else if ( ( section_version > V_WEAPONS ) )
12620 {
12621 al_trace("Cannot read .zwpnspr packfile made using V_WEAPONS (%d)\n", section_version);
12622 return 0;
12623
12624 }
12625 else
12626 {
12627 al_trace("Reading a .zwpnspr packfile made in ZC Version: %x, Build: %d\n", zversion, zbuild);
12628 }
12629
12630 char tmp_wpn_name[64];
12631 memset(tmp_wpn_name,0,64);
12632 if(!pfread(&tmp_wpn_name, 64, f))
12633 {
12634 return 0;
12635 }
12636
12637 word oldtile = 0;
12638 if(section_version < 8)
12639 if(!p_igetw(&oldtile,f))
12640 return 0;
12641
12642 if(!p_getc(&tempwpnspr.misc,f))
12643 {
12644 return 0;
12645 }
12646
12647 if(!p_getc(&tempwpnspr.csets,f))
12648 {
12649 return 0;
12650 }
12651
12652 if(!p_getc(&tempwpnspr.frames,f))
12653 {
12654 return 0;
12655 }
12656
12657 if(!p_getc(&tempwpnspr.speed,f))
12658 {
12659 return 0;
12660 }
12661
12662 if(!p_getc(&tempwpnspr.type,f))
12663 {
12664 return 0;
12665 }
12666
12667 if(!p_igetw(&tempwpnspr.script,f))
12668 {
12669 return 0;
12670 }
12671
12672 //2.55 starts here
12673 if ( zversion >= 0x255 )
12674 {
12675 if ( section_version >= 7 )
12676 {
12677 if(!p_igetl(&tempwpnspr.tile,f))
12678 {
12679 return 0;
12680 }
12681 }
12682 }
12683 if ( zversion < 0x255 )
12684 {
12685 tempwpnspr.tile = oldtile;
12686 }
12687 ::memcpy( &(wpnsbuf[biw[index].i]),&tempwpnspr, sizeof(wpndata));
12688 ::memcpy(weapon_string[biw[index].i], tmp_wpn_name, 64);
12689
12690 return 1;
12691 }
12692
12693 static int32_t seldata_copy;
12694 static void (*seldata_paste_func)(int32_t, int32_t);
12695
12696 void seldata_rclick_func(int32_t index, int32_t x, int32_t y)
12697 {
12698 NewMenu rcmenu {
12699 { "&Copy", [&](){seldata_copy = index;} },
12700 { "Paste", "&v", [&]()
12701 {
12702 seldata_paste_func(seldata_copy, index);
12703 mark_save_dirty();
12704 }, 0, seldata_copy < 0 ? MFL_DIS : 0 },
12705 };
12706 rcmenu.pop(x, y);
12707 }
12708
12709 int32_t select_data(const char *prompt,int32_t index,const char *(proc)(int32_t,int32_t*), FONT *title_font, void (*copyFunc)(int32_t, int32_t))
12710 {
12711 if(proc==NULL)
12712 return -1;
12713
12714 list_dlg[0].dp=(void *)prompt;
12715 list_dlg[0].dp2=title_font;
12716 list_dlg[2].d1=index;
12717 ListData select_list(proc, &font);
12718 list_dlg[2].dp=(void *) &select_list;
12719
12720 large_dialog(list_dlg);
12721
12722 seldata_copy=-1;
12723 seldata_paste_func=copyFunc;
12724 if(copyFunc)
12725 {
12726 list_dlg[2].flags|=D_USER<<1;
12727 list_dlg[2].dp3=(void*)seldata_rclick_func;
12728 }
12729 else
12730 {
12731 list_dlg[2].flags&=~(D_USER<<1);
12732 list_dlg[2].dp3=0;
12733 }
12734
12735 int32_t ret=do_zqdialog(list_dlg,2);
12736
12737 if(ret==0||ret==4)
12738 {
12739 position_mouse_z(0);
12740 return -1;
12741 }
12742
12743 return list_dlg[2].d1;
12744 }
12745
12746 int32_t select_data(const char *prompt,int32_t index,const char *(proc)(int32_t,int32_t*), const char *b1, const char *b2, FONT *title_font, void (*copyFunc)(int32_t, int32_t))
12747 {
12748 if(proc==NULL)
12749 return -1;
12750
12751 list_dlg[0].dp=(void *)prompt;
12752 list_dlg[0].dp2=title_font;
12753 list_dlg[2].d1=index;
12754 ListData select_data_list(proc, &font);
12755 list_dlg[2].dp=(void *) &select_data_list;
12756 list_dlg[3].dp=(void *)b1;
12757 list_dlg[4].dp=(void *)b2;
12758
12759 large_dialog(list_dlg);
12760
12761 seldata_copy=-1;
12762 seldata_paste_func=copyFunc;
12763 if(copyFunc)
12764 {
12765 list_dlg[2].flags|=D_USER<<1;
12766 list_dlg[2].dp3=(void*)seldata_rclick_func;
12767 }
12768 else
12769 {
12770 list_dlg[2].flags&=~(D_USER<<1);
12771 list_dlg[2].dp3=0;
12772 }
12773
12774 int32_t ret = do_zqdialog(list_dlg,2);
12775 list_dlg[3].dp=(void *) "OK";
12776 list_dlg[4].dp=(void *) "Cancel";
12777
12778 if(ret==0||ret==4)
12779 {
12780 position_mouse_z(0);
12781 return -1;
12782 }
12783
12784 position_mouse_z(0);
12785 return list_dlg[2].d1;
12786 }
12787
12788 int32_t onScreenScript()
12789 {
12790 call_screendata_dialog(7);
12791 return D_O_K;
12792 }
12793
12794 int32_t onScrData()
12795 {
12796 restore_mouse();
12797 call_screendata_dialog();
12798 return D_O_K;
12799 }
12800
12801 static char number_str_buf[MIDI_TRACK_BUFFER_SIZE];
12802 int32_t number_list_size=1;
12803 bool number_list_zero=false;
12804
12805 const char *numberlist(int32_t index, int32_t *list_size)
12806 {
12807 if(index>=0)
12808 {
12809 bound(index,0,number_list_size-1);
12810 sprintf(number_str_buf,"%d",index+(number_list_zero?0:1));
12811 return number_str_buf;
12812 }
12813
12814 *list_size=number_list_size;
12815 return NULL;
12816 }
12817
12818 static char dmap_str_buf[37];
12819 int32_t dmap_list_size=MAXDMAPS;
12820 bool dmap_list_zero=true;
12821
12822 const char *dmaplist(int32_t index, int32_t *list_size)
12823 {
12824 if(index>=0)
12825 {
12826 bound(index,0,dmap_list_size-1);
12827 sprintf(dmap_str_buf,"%3d-%s",index+(dmap_list_zero?0:1), DMaps[index].name);
12828 return dmap_str_buf;
12829 }
12830
12831 *list_size=dmap_list_size;
12832 return NULL;
12833 }
12834
12835 const char *gotomaplist(int32_t index, int32_t *list_size)
12836 {
12837 if(index>=0)
12838 {
12839 bound(index,0,map_count-1);
12840 sprintf(number_str_buf,"%d",index+1);
12841 return number_str_buf;
12842 }
12843
12844 *list_size = map_count;
12845 return NULL;
12846 }
12847
12848 const char *levelnumlist(int32_t index, int32_t *list_size)
12849 {
12850 if(index>=0)
12851 {
12852 bound(index,0,0xFFF);
12853 sprintf(number_str_buf,"%.3X - %s",index,palnames[index]);
12854 return number_str_buf;
12855 }
12856
12857 *list_size=MAXLEVELS;
12858 return NULL;
12859 }
12860
12861 static char shop_str_buf[40];
12862 int32_t shop_list_size=1;
12863
12864 const char *shoplist(int32_t index, int32_t *list_size)
12865 {
12866 if(index>=0)
12867 {
12868 bound(index,0,shop_list_size-1);
12869 sprintf(shop_str_buf,"%3d: %s",index,QMisc.shop[index].name);
12870 return shop_str_buf;
12871 }
12872
12873 *list_size=shop_list_size;
12874 return NULL;
12875 }
12876
12877 static char bottle_str_buf[40];
12878 int32_t bottle_list_size=1;
12879
12880 const char *bottlelist(int32_t index, int32_t *list_size)
12881 {
12882 if(index>=0)
12883 {
12884 bound(index,0,bottle_list_size-1);
12885 sprintf(bottle_str_buf,"%2d: %s",index+1,QMisc.bottle_types[index].name);
12886 return bottle_str_buf;
12887 }
12888
12889 *list_size=bottle_list_size;
12890 return NULL;
12891 }
12892
12893 static char bottleshop_str_buf[40];
12894 int32_t bottleshop_list_size=1;
12895
12896 const char *bottleshoplist(int32_t index, int32_t *list_size)
12897 {
12898 if(index>=0)
12899 {
12900 bound(index,0,bottleshop_list_size-1);
12901 sprintf(bottleshop_str_buf,"%3d: %s",index,QMisc.bottle_shop_types[index].name);
12902 return bottleshop_str_buf;
12903 }
12904
12905 *list_size=bottleshop_list_size;
12906 return NULL;
12907 }
12908
12909 static char info_str_buf[40];
12910 int32_t info_list_size=1;
12911
12912 const char *infolist(int32_t index, int32_t *list_size)
12913 {
12914 if(index>=0)
12915 {
12916 bound(index,0,info_list_size-1);
12917 sprintf(info_str_buf,"%3d: %s",index,QMisc.info[index].name);
12918 return info_str_buf;
12919 }
12920
12921 *list_size=info_list_size;
12922 return NULL;
12923 }
12924
12925 bool mapcount_will_affect_layers(word newmapcount)
12926 {
12927 for(int32_t i=0; i<(newmapcount)*MAPSCRS; i++)
12928 {
12929 mapscr *layerchecker=&TheMaps[i];
12930
12931 for(int32_t j=0; j<6; j++)
12932 {
12933 if(layerchecker->layermap[j]>(newmapcount))
12934 {
12935 return true;
12936 }
12937 }
12938 }
12939 return false;
12940 }
12941
12942 void update_map_count(word newmapcount)
12943 {
12944 if(map_count == newmapcount) return;
12945 mark_save_dirty();
12946 setMapCount2(newmapcount);
12947 //Prevent the nine 'last mapscreen' buttons from pointing to invlid locations
12948 //if the user reduces the mapcount. -Z ( 23rd September, 2019 )
12949 for ( int32_t q = 0; q < 9; q++ )
12950 {
12951 map_page[q].map = ( map_page[q].map > newmapcount-1 ) ? newmapcount-1 : map_page[q].map;
12952 }
12953 for(int32_t i=0; i<(newmapcount)*MAPSCRS; i++)
12954 {
12955 fix_layers(&TheMaps[i], false);
12956 }
12957
12958 refresh(rMAP+rSCRMAP+rMENU);
12959 }
12960
12961 int32_t onGotoMap()
12962 {
12963 int32_t ret = select_data("Goto Map",Map.getCurrMap(),gotomaplist,get_zc_font(font_lfont));
12964
12965 if(ret >= 0)
12966 {
12967 int32_t m=Map.getCurrMap();
12968 Map.setCurrMap(ret);
12969 }
12970
12971 refresh(rALL);
12972 return D_O_K;
12973 }
12974
12975 int32_t onFlags()
12976 {
12977 restore_mouse();
12978 int32_t ret=select_cflag("Select Combo Flag",Flag);
12979 position_mouse_z(0);
12980
12981 if(ret>=0)
12982 {
12983 Flag=ret;
12984 refresh(rMENU);
12985 doflags();
12986 }
12987
12988 return D_O_K;
12989 }
12990
12991 static DIALOG usedcombo_list_dlg[] =
12992 {
12993 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
12994 12 { jwin_win_proc, 60-12, 40, 200+24, 148, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Combos Used", NULL, NULL },
12995 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
12996 12 { jwin_textbox_proc, 72-12, 60+4, 176+24+1, 92+4, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, NULL, NULL, NULL },
12997 12 { jwin_button_proc, 130, 163, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
12998 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
12999 };
13000
13001
13002
13003 int32_t onUsedCombos()
13004 {
13005 restore_mouse();
13006 usedcombo_list_dlg[0].dp2=get_zc_font(font_lfont);
13007
13008 int32_t usedcombos[7][300][2];
13009 char combolist_text[65536];
13010 char temptext[80];
13011
13012 int32_t drawmap=Map.getCurrMap();
13013 int32_t drawscr=Map.getCurrScr();
13014 int32_t counter[7];
13015
13016 for(int32_t layer=0; layer<7; ++layer)
13017 {
13018 counter[layer]=0;
13019
13020 if(layer==0)
13021 {
13022 drawmap=Map.getCurrMap();
13023 drawscr=Map.getCurrScr();
13024 }
13025 else
13026 {
13027 drawmap=Map.CurrScr()->layermap[layer-1]-1;
13028 drawscr=Map.CurrScr()->layerscreen[layer-1];
13029 }
13030 mapscr* draw_mapscr = Map.AbsoluteScr(drawmap, drawscr);
13031 if(!draw_mapscr) continue;
13032
13033 usedcombos[layer][0][0]=draw_mapscr->data[0];
13034 usedcombos[layer][0][1]=1;
13035 counter[layer]=1;
13036
13037 for(int32_t i=1; i<176; ++i)
13038 {
13039 bool used=false;
13040
13041 for(int32_t j=0; j<counter[layer]; ++j)
13042 {
13043 if(usedcombos[layer][j][0]==draw_mapscr->data[i])
13044 {
13045 ++usedcombos[layer][j][1];
13046 used=true;
13047 break;
13048 }
13049 }
13050
13051 if(!used)
13052 {
13053 usedcombos[layer][counter[layer]][0]=draw_mapscr->data[i];
13054 usedcombos[layer][counter[layer]][1]=1;
13055 ++counter[layer];
13056 }
13057 }
13058
13059 for(int32_t i=0; i<counter[layer]-1; i++)
13060 {
13061 for(int32_t j=i+1; j<counter[layer]; j++)
13062 {
13063 if(usedcombos[layer][i][0]>usedcombos[layer][j][0])
13064 {
13065 zc_swap(usedcombos[layer][i][0],usedcombos[layer][j][0]);
13066 zc_swap(usedcombos[layer][i][1],usedcombos[layer][j][1]);
13067 }
13068 }
13069 }
13070 }
13071
13072 sprintf(combolist_text, " ");
13073
13074 for(int32_t layer=0; layer<7; ++layer)
13075 {
13076 if(counter[layer]>0)
13077 {
13078 if(layer>0)
13079 {
13080 strcat(combolist_text, "\n");
13081 }
13082
13083 sprintf(temptext, "Combos on layer %d\n-----------------\n", layer);
13084 strcat(combolist_text, temptext);
13085
13086 for(int32_t i=0; i<counter[layer]; i++)
13087 {
13088 if((i<counter[layer]-1) && (((usedcombos[layer][i][1]==usedcombos[layer][i+1][1]&&(usedcombos[layer][i][0]+1==usedcombos[layer][i+1][0])) && ((i==0) || ((usedcombos[layer][i][1]!=usedcombos[layer][i-1][1])||((usedcombos[layer][i][0]-1!=usedcombos[layer][i-1][0])))))))
13089 {
13090 sprintf(temptext, "%5d ", usedcombos[layer][i][0]);
13091 strcat(combolist_text, temptext);
13092 }
13093 else if(((i>0) && (((usedcombos[layer][i][1]==usedcombos[layer][i-1][1])&&((usedcombos[layer][i][0]-1==usedcombos[layer][i-1][0]))) && ((i==counter[layer]-1) || ((usedcombos[layer][i][1]!=usedcombos[layer][i+1][1])||((usedcombos[layer][i][0]+1!=usedcombos[layer][i+1][0])))))))
13094 {
13095 sprintf(temptext, "- %5d (%3d)\n", usedcombos[layer][i][0],usedcombos[layer][i][1]);
13096 strcat(combolist_text, temptext);
13097 }
13098 else if(((i==0) && ((usedcombos[layer][i][1]!=usedcombos[layer][i+1][1])||((usedcombos[layer][i][0]+1!=usedcombos[layer][i+1][0]))))||
13099 ((i==counter[layer]-1) && ((usedcombos[layer][i][1]!=usedcombos[layer][i-1][1])||((usedcombos[layer][i][0]-1!=usedcombos[layer][i-1][0]))))||
13100 ((i>0) && (i<counter[layer]-1) && ((usedcombos[layer][i][1]!=usedcombos[layer][i+1][1])||((usedcombos[layer][i][0]+1!=usedcombos[layer][i+1][0]))) && ((usedcombos[layer][i][1]!=usedcombos[layer][i-1][1])||((usedcombos[layer][i][0]-1!=usedcombos[layer][i-1][0])))))
13101 {
13102 sprintf(temptext, " %5d (%3d)\n", usedcombos[layer][i][0],usedcombos[layer][i][1]);
13103 strcat(combolist_text, temptext);
13104 }
13105 }
13106 }
13107 }
13108
13109 strcat(combolist_text, "\n");
13110 usedcombo_list_dlg[2].dp=combolist_text;
13111 usedcombo_list_dlg[2].d2=0;
13112
13113 large_dialog(usedcombo_list_dlg);
13114
13115 do_zqdialog(usedcombo_list_dlg,2);
13116 position_mouse_z(0);
13117 return D_O_K;
13118 }
13119
13120 int32_t onItem()
13121 {
13122 restore_mouse();
13123 int32_t exit_status;
13124 int32_t current_item=Map.CurrScr()->hasitem != 0 ? Map.CurrScr()->item : -1;
13125
13126 ItemListerDialog(current_item,true).show();
13127 if(current_item != lister_sel_val)
13128 {
13129 if(lister_sel_val>=0)
13130 {
13131 mark_save_dirty();
13132 Map.CurrScr()->item = lister_sel_val;
13133 Map.CurrScr()->hasitem = true;
13134 }
13135 else
13136 {
13137 mark_save_dirty();
13138 Map.CurrScr()->hasitem = false;
13139 }
13140 }
13141
13142 refresh(rMAP+rMENU);
13143 return D_O_K;
13144 }
13145
13146 void call_room_dlg(mapscr* scr);
13147 int32_t onRoom()
13148 {
13149 restore_mouse();
13150 auto* scr = Map.CurrScr();
13151 call_room_dlg(scr);
13152
13153 refresh(rMAP+rMENU);
13154 return D_O_K;
13155 }
13156
13157 int32_t onEndString()
13158 {
13159 int32_t ret=select_data("Select Ending String",QMisc.endstring,msgslist,get_zc_font(font_lfont));
13160
13161 if(ret>=0)
13162 {
13163 mark_save_dirty();
13164 QMisc.endstring=msglistcache[ret];
13165 }
13166
13167 refresh(rMENU);
13168 return D_O_K;
13169 }
13170
13171 12 static ListData levelnum_list(levelnumlist, &font);
13172
13173 static DIALOG screen_pal_dlg[] =
13174 {
13175 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
13176 12 { jwin_win_proc, 60-12, 40, 200-16, 96, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Select Palette", NULL, NULL },
13177 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
13178 12 { jwin_droplist_proc, 72-12, 84+4, 161, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, (void *) &levelnum_list, NULL, NULL },
13179 12 { jwin_button_proc, 70, 111, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
13180 12 { jwin_button_proc, 150, 111, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
13181 12 { jwin_text_proc, 72-12, 60+4, 168, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Note: This does not affect how the", NULL, NULL },
13182 12 { jwin_text_proc, 72-12, 72+4, 168, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "room will be displayed in-game!", NULL, NULL },
13183 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
13184 };
13185 // return list_dlg[2].d1;
13186
13187 int32_t onScreenPalette()
13188 {
13189 restore_mouse();
13190 screen_pal_dlg[0].dp2=get_zc_font(font_lfont);
13191 auto oldcol = screen_pal_dlg[2].d1 = Map.getcolor();
13192
13193 large_dialog(screen_pal_dlg);
13194 auto old_valid = Map.CurrScr()->valid;
13195 pause_dlg_tint(true);
13196 zq_set_screen_never_freeze(true);
13197 while(true)
13198 {
13199 auto ret = do_zqdialog(screen_pal_dlg,2);
13200 if(ret == 2)
13201 {
13202 Map.setcolor(screen_pal_dlg[2].d1);
13203 refresh(rALL);
13204 }
13205 else
13206 {
13207 if(ret == 3)
13208 {
13209 if(screen_pal_dlg[2].d1 != oldcol)
13210 mark_save_dirty();
13211 Map.setcolor(screen_pal_dlg[2].d1);
13212 }
13213 else
13214 {
13215 Map.setcolor(oldcol);
13216 Map.CurrScr()->valid = old_valid;
13217 }
13218 refresh(rALL);
13219 break;
13220 }
13221 }
13222 pause_dlg_tint(false);
13223 zq_set_screen_never_freeze(false);
13224
13225 rebuild_trans_table();
13226
13227 return D_O_K;
13228 }
13229
13230 int32_t onDecScrPal()
13231 {
13232 if(DisableLPalShortcuts)
13233 {
13234 lpal_dsa();
13235 return D_O_K;
13236 }
13237 restore_mouse();
13238 int32_t c = Map.getcolor();
13239 c = (c+511) % 512;
13240 Map.setcolor(c);
13241 refresh(rALL);
13242 mark_save_dirty();
13243 return D_O_K;
13244 }
13245
13246 int32_t onIncScrPal()
13247 {
13248 if(DisableLPalShortcuts)
13249 {
13250 lpal_dsa();
13251 return D_O_K;
13252 }
13253 restore_mouse();
13254 int32_t c = Map.getcolor();
13255 c = (c+1)%512;
13256 Map.setcolor(c);
13257 refresh(rALL);
13258 mark_save_dirty();
13259 return D_O_K;
13260 }
13261
13262 int32_t PalWrap(int32_t kX, int32_t const kLowerBound, int32_t const kUpperBound)
13263 {
13264 int32_t range_size = kUpperBound - kLowerBound + 1;
13265
13266 if (kX < kLowerBound)
13267 kX += range_size * ((kLowerBound - kX) / range_size + 1);
13268
13269 return kLowerBound + (kX - kLowerBound) % range_size;
13270 }
13271
13272 int32_t onDecScrPal16()
13273 {
13274 if(DisableLPalShortcuts)
13275 {
13276 lpal_dsa();
13277 return D_O_K;
13278 }
13279 restore_mouse();
13280 int32_t c = Map.getcolor();
13281 c = PalWrap( ( c-0x10 ), 0, 511 );
13282 Map.setcolor(c);
13283 refresh(rALL);
13284 mark_save_dirty();
13285 return D_O_K;
13286 }
13287
13288 int32_t onIncScrPal16()
13289 {
13290 if(DisableLPalShortcuts)
13291 {
13292 lpal_dsa();
13293 return D_O_K;
13294 }
13295 restore_mouse();
13296 int32_t c = Map.getcolor();
13297 c = PalWrap( ( c+0x10 ), 0, 511 );
13298 Map.setcolor(c);
13299 refresh(rALL);
13300 mark_save_dirty();
13301 return D_O_K;
13302 }
13303
13304 int32_t onZoomIn()
13305 {
13306 change_mapscr_zoom(-1);
13307 return D_O_K;
13308 }
13309
13310 int32_t onZoomOut()
13311 {
13312 change_mapscr_zoom(1);
13313 return D_O_K;
13314 }
13315
13316 int32_t d_ndroplist_proc(int32_t msg,DIALOG *d,int32_t c)
13317 {
13318 int32_t ret = jwin_droplist_proc(msg,d,c);
13319
13320 // The only place this proc is used is in the info type editor.
13321 // If it's ever used anywhere else, this will probably need to be changed.
13322 // Maybe add a flag for it or something.
13323 int32_t msgID=msg_at_pos(d->d1);
13324
13325 switch(msg)
13326 {
13327 case MSG_DRAW:
13328 case MSG_CHAR:
13329 case MSG_CLICK:
13330 textprintf_ex(screen,font,d->x - 48,d->y + 4,jwin_pal[jcBOXFG],jwin_pal[jcBOX],"%5d",msgID);
13331 }
13332
13333 return ret;
13334 }
13335
13336 int32_t d_idroplist_proc(int32_t msg,DIALOG *d,int32_t c)
13337 {
13338 int32_t ret = jwin_droplist_proc(msg,d,c);
13339
13340 switch(msg)
13341 {
13342 case MSG_DRAW:
13343 case MSG_CHAR:
13344 case MSG_CLICK:
13345 int32_t tile = bii[d->d1].i >=0 ? itemsbuf[bii[d->d1].i].tile : 0;
13346 int32_t cset = bii[d->d1].i >=0 ? itemsbuf[bii[d->d1].i].csets&15 : 0;
13347 int32_t x = d->x + d->w + 4;
13348 int32_t y = d->y - 8;
13349 int32_t w = 32;
13350 int32_t h = 32;
13351
13352 BITMAP *buf = create_bitmap_ex(8,16,16);
13353 BITMAP *bigbmp = create_bitmap_ex(8,w,h);
13354
13355 if(buf && bigbmp)
13356 {
13357 clear_bitmap(buf);
13358
13359 if(tile)
13360 overtile16(buf, tile,0,0,cset,0);
13361
13362 stretch_blit(buf, bigbmp, 0,0, 16, 16, 0, 0, w, h);
13363 destroy_bitmap(buf);
13364 jwin_draw_frame(screen,x,y,w+4,h+4,FR_DEEP);
13365 blit(bigbmp,screen,0,0,x+2,y+2,w,h);
13366 destroy_bitmap(bigbmp);
13367 }
13368
13369 }
13370
13371 return ret;
13372 }
13373
13374 int32_t d_nidroplist_proc(int32_t msg,DIALOG *d,int32_t c)
13375 {
13376 int32_t ret = d_idroplist_proc(msg,d,c);
13377
13378 switch(msg)
13379 {
13380 case MSG_DRAW:
13381 case MSG_CHAR:
13382 case MSG_CLICK:
13383 textprintf_ex(screen,font,d->x - 48,d->y + 4,jwin_pal[jcBOXFG],jwin_pal[jcBOX],"%5d",bii[d->d1].i);
13384 }
13385
13386 return ret;
13387 }
13388
13389 // Triforce pieces
13390 static byte triframe_points[9*4] =
13391 {
13392 0,2,2,0, 2,0,4,2, 0,2,4,2, 1,1,3,1, 2,0,2,2,
13393 1,1,1,2, 1,1,2,2, 3,1,3,2, 3,1,2,2
13394 };
13395
13396 int32_t d_tri_frame_proc(int32_t msg,DIALOG *d,int32_t c)
13397 {
13398 //these are here to bypass compiler warnings about unused arguments
13399 c=c;
13400
13401 if(msg==MSG_DRAW)
13402 {
13403 int32_t x[5],y[3];
13404
13405 x[0]=d->x;
13406 x[1]=d->x+(d->w>>2);
13407 x[2]=d->x+(d->w>>1);
13408 x[3]=d->x+(d->w>>1)+(d->w>>2);
13409 x[4]=d->x+d->w;
13410 y[0]=d->y;
13411 y[1]=d->y+(d->h>>1);
13412 y[2]=d->y+d->h;
13413
13414 byte *p = triframe_points;
13415
13416 for(int32_t i=0; i<9; i++)
13417 {
13418 line(screen,x[*p],y[*(p+1)],x[*(p+2)],y[*(p+3)],d->fg);
13419 p+=4;
13420 }
13421 }
13422
13423 return D_O_K;
13424 }
13425
13426 int32_t d_tri_edit_proc(int32_t msg,DIALOG *d,int32_t c)
13427 {
13428 jwin_button_proc(msg,d,c);
13429
13430 if(msg==MSG_CLICK)
13431 {
13432 int v;
13433 if (auto num = call_get_num("Piece Number", d->d1, 8, 1))
13434 v = *num;
13435 else return D_O_K;
13436
13437 if(v!=d->d1)
13438 {
13439 DIALOG *tp = d - d->d2;
13440
13441 for(int32_t i=0; i<8; i++)
13442 {
13443 if(tp->d1==v)
13444 {
13445 tp->d1 = d->d1;
13446 ((char*)(tp->dp))[0] = d->d1+'0';
13447 jwin_button_proc(MSG_DRAW,tp,0);
13448 }
13449
13450 ++tp;
13451 }
13452
13453 d->d1 = v;
13454 ((char*)(d->dp))[0] = v+'0';
13455 }
13456
13457 d->flags = 0;
13458 jwin_button_proc(MSG_DRAW,d,0);
13459 }
13460
13461 return D_O_K;
13462 }
13463
13464 static DIALOG tp_dlg[] =
13465 {
13466 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
13467 12 { jwin_win_proc, 56, 32, 208, 160, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Triforce Pieces", NULL, NULL },
13468 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
13469 12 { d_tri_frame_proc, 64, 56, 192, 96, jwin_pal[jcBOXFG], jwin_pal[jcBOX], 0, 0, 0, 0, NULL, NULL, NULL },
13470 // 3
13471 12 { d_tri_edit_proc, 138, 82, 17, 17, vc(14), vc(1), 0, 0, 0, 0, (void *) "1", NULL, NULL },
13472 12 { d_tri_edit_proc, 166, 82, 17, 17, vc(14), vc(1), 0, 0, 0, 1, (void *) "2", NULL, NULL },
13473 12 { d_tri_edit_proc, 90, 130, 17, 17, vc(14), vc(1), 0, 0, 0, 2, (void *) "3", NULL, NULL },
13474 12 { d_tri_edit_proc, 214, 130, 17, 17, vc(14), vc(1), 0, 0, 0, 3, (void *) "4", NULL, NULL },
13475 // 7
13476 12 { d_tri_edit_proc, 138, 110, 17, 17, vc(14), vc(1), 0, 0, 0, 4, (void *) "5", NULL, NULL },
13477 12 { d_tri_edit_proc, 118, 130, 17, 17, vc(14), vc(1), 0, 0, 0, 5, (void *) "6", NULL, NULL },
13478 12 { d_tri_edit_proc, 166, 110, 17, 17, vc(14), vc(1), 0, 0, 0, 6, (void *) "7", NULL, NULL },
13479 12 { d_tri_edit_proc, 186, 130, 17, 17, vc(14), vc(1), 0, 0, 0, 7, (void *) "8", NULL, NULL },
13480 // 11
13481 12 { jwin_button_proc, 90, 166, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
13482 12 { jwin_button_proc, 170, 166, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
13483 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
13484 };
13485
13486 int32_t onTriPieces()
13487 {
13488 tp_dlg[0].dp2=get_zc_font(font_lfont);
13489 char temptext[8][2];
13490
13491 for(int32_t i=0; i<8; i++)
13492 {
13493 tp_dlg[i+3].d1 = QMisc.triforce[i];
13494 // ((char*)(tp_dlg[i+3].dp))[0] = QMisc.triforce[i]+'0';
13495 sprintf(temptext[i], "%d", QMisc.triforce[i]);
13496 tp_dlg[i+3].dp=temptext[i];
13497 }
13498
13499 large_dialog(tp_dlg);
13500
13501 if(do_zqdialog(tp_dlg,-1) == 11)
13502 {
13503 mark_save_dirty();
13504
13505 for(int32_t i=0; i<8; i++)
13506 QMisc.triforce[i] = tp_dlg[i+3].d1;
13507 }
13508
13509 return D_O_K;
13510 }
13511
13512 bool small_dmap=false;
13513
13514 int32_t d_hexedit_proc(int32_t msg,DIALOG *d,int32_t c)
13515 {
13516 return jwin_hexedit_proc(msg,d,c);
13517 }
13518
13519 void drawgrid(BITMAP *dest,int32_t x,int32_t y,int32_t grid,int32_t fg,int32_t bg,int32_t div)
13520 {
13521 if(div!=-1)
13522 rectfill(dest,x-1,y-1,x+63,y+3,div);
13523
13524 for(int32_t dx=0; dx<64; dx+=8)
13525 {
13526 if(grid&0x80)
13527 rectfill(dest,x+dx,y,x+dx+6,y+2,fg);
13528 else if(bg!=-1)
13529 rectfill(dest,x+dx,y,x+dx+6,y+2,bg);
13530
13531 grid<<=1;
13532 }
13533 }
13534
13535 void drawovergrid(BITMAP *dest,int32_t x,int32_t y,int32_t grid,int32_t color,int32_t div)
13536 {
13537 if(div!=-1)
13538 rectfill(dest,x-1,y-1,x+63,y+3,div);
13539
13540 for(int32_t dx=0; dx<64; dx+=4)
13541 {
13542 rectfill(dest,x+dx,y,x+dx+2,y+2,color);
13543 grid<<=1;
13544 }
13545 }
13546
13547 void drawgrid_s(BITMAP *dest,int32_t x,int32_t y,int32_t grid,int32_t fg,int32_t bg,int32_t div)
13548 {
13549 rectfill(dest,x-1,y-1,x+63,y+3,div);
13550
13551 for(int32_t dx=0; dx<64; dx+=8)
13552 {
13553 rectfill(dest,x+dx,y,x+dx+6,y+2,bg);
13554
13555 if(grid&0x80)
13556 rectfill(dest,x+dx+2,y,x+dx+4,y+2,fg);
13557
13558 grid<<=1;
13559 }
13560 }
13561
13562 void drawdmap(int32_t dmap)
13563 {
13564 int32_t c;
13565 zcolors mc=QMisc.colors;
13566
13567 switch((DMaps[dmap].type&dmfTYPE))
13568 {
13569 case dmDNGN:
13570 case dmCAVE:
13571 clear_bitmap(dmapbmp_small);
13572
13573 if(DMaps[dmap].minimap_tile[1])
13574 ;
13575 // overworld_map_tile overrides the NES minimap. dungeon_map_tile does not.
13576 else for(int32_t y=1; y<33; y+=4)
13577 drawgrid(dmapbmp_small,0,y,DMaps[dmap].grid[y>>2], DMaps[dmap].flags&dmfMINIMAPCOLORFIX ? mc.cave_fg : mc.dngn_fg, -1, -1);
13578
13579 c=DMaps[dmap].compass;
13580 // rectfill(dmapbmp,(c&15)*8+3,(c>>4)*4+1,(c&15)*8+5,(c>>4)*4+3,dvc(2*4));
13581 rectfill(dmapbmp_small,(c&15)*8+3,(c>>4)*4+1,(c&15)*8+5,(c>>4)*4+3,vc(4));
13582 c=DMaps[dmap].cont;
13583 rectfill(dmapbmp_small,(c&15)*8+3,(c>>4)*4+1,(c&15)*8+5,(c>>4)*4+3,vc(10));
13584 break;
13585
13586 case dmOVERW:
13587 clear_bitmap(dmapbmp_small);
13588
13589 if(DMaps[dmap].minimap_tile[1])
13590 ;
13591 else if(!mc.overworld_map_tile)
13592 for(int32_t y=1; y<33; y+=4)
13593 drawovergrid(dmapbmp_small,1,y,DMaps[dmap].grid[y>>2],mc.overw_bg,vc(0));
13594
13595 c=DMaps[dmap].cont;
13596 rectfill(dmapbmp_small,(c&15)*4+1,(c>>4)*4+1,(c&15)*4+3,(c>>4)*4+3,vc(10));
13597 break;
13598
13599 case dmBSOVERW:
13600 clear_bitmap(dmapbmp_small);
13601
13602 if(DMaps[dmap].minimap_tile[1])
13603 ;
13604 else if(!mc.overworld_map_tile)
13605 for(int32_t y=1; y<33; y+=4)
13606 // drawgrid_s(dmapbmp,1,y,DMaps[dmap].grid[y>>2],dvc(2*4),dvc(2*3),dvc(3+4));
13607 drawgrid_s(dmapbmp_small,0,y,DMaps[dmap].grid[y>>2],mc.bs_goal,mc.bs_dk,vc(14));
13608
13609 c=DMaps[dmap].cont;
13610 rectfill(dmapbmp_small,(c&15)*8+3,(c>>4)*4+1,(c&15)*8+5,(c>>4)*4+3,vc(10));
13611 break;
13612 }
13613 }
13614
13615 void drawdmap_screen(int32_t x, int32_t y, int32_t w, int32_t h, int32_t dmap)
13616 {
13617 BITMAP *tempbmp = create_bitmap_ex(8,w,h);
13618 clear_to_color(tempbmp, vc(0));
13619 zcolors mc=QMisc.colors;
13620
13621 // rectfill(tempbmp,x,y,x+w-1,y+h-1,vc(0));
13622
13623 if(DMaps[dmap].minimap_tile[1])
13624 {
13625 draw_block(tempbmp,0,0,DMaps[dmap].minimap_tile[1],DMaps[dmap].minimap_cset[1],5,3);
13626 }
13627 else if(((DMaps[dmap].type&dmfTYPE)==dmDNGN || (DMaps[dmap].type&dmfTYPE)==dmCAVE) && mc.dungeon_map_tile)
13628 {
13629 draw_block(tempbmp,0,0,mc.dungeon_map_tile,mc.dungeon_map_cset,5,3);
13630 }
13631 else if(((DMaps[dmap].type&dmfTYPE)==dmOVERW || (DMaps[dmap].type&dmfTYPE)==dmBSOVERW) && mc.overworld_map_tile)
13632 {
13633 draw_block(tempbmp,0,0,mc.overworld_map_tile,mc.overworld_map_cset,5,3);
13634 }
13635
13636 masked_blit(dmapbmp_small,tempbmp,0,0,8,7,65,33);
13637
13638 blit(tempbmp,screen,0,0,x,y,w,h);
13639 destroy_bitmap(tempbmp);
13640
13641 }
13642
13643 int32_t d_dropdmaplist_proc(int32_t msg,DIALOG *d,int32_t c)
13644 {
13645 if(msg==MSG_DRAW)
13646 {
13647 int32_t dmap = d->d1;
13648 int32_t *xy = (int32_t*)(d->dp3);
13649 float temp_scale = 1.5;
13650
13651 drawdmap(dmap);
13652
13653 if(xy[0]>-1000&&xy[1]>-1000)
13654 {
13655 int32_t x = d->x+int32_t((xy[0]-2)*temp_scale);
13656 int32_t y = d->y+int32_t((xy[1]-2)*temp_scale);
13657 int32_t w = 84;
13658 int32_t h = 52;
13659 jwin_draw_frame(screen,x,y,w,h,FR_DEEP);
13660 drawdmap_screen(x+2,y+2,w-4,h-4,dmap);
13661 }
13662
13663 if(xy[2]>-1000&&xy[3]>-1000)
13664 {
13665 textprintf_ex(screen,get_zc_font(font_lfont_l),d->x+int32_t((xy[2])*temp_scale),d->y+int32_t((xy[3])*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Map: %-3d",DMaps[d->d1].map+1);
13666 }
13667
13668 if(xy[4]>-1000&&xy[5]>-1000)
13669 {
13670 textprintf_ex(screen,get_zc_font(font_lfont_l),d->x+int32_t((xy[4])*temp_scale),d->y+int32_t((xy[5])*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Level: %-3d",DMaps[d->d1].level);
13671 }
13672 }
13673
13674 return jwin_droplist_proc(msg,d,c);
13675 }
13676
13677 void drawxmap(ALLEGRO_BITMAP* dest, int32_t themap, int32_t xoff, bool large, int dx, int dy)
13678 {
13679 ALLEGRO_STATE old_state;
13680 al_store_state(&old_state, ALLEGRO_STATE_TARGET_BITMAP);
13681
13682 al_set_target_bitmap(dest);
13683 al_clear_to_color(al_map_rgba(0, 0, 0, 0));
13684
13685 int32_t cols = (large ? 8 : 16);
13686 int32_t col_width = large ? 22 : 11;
13687 int32_t dot_width = (large ? 6 : 4);
13688 int32_t dot_offset = (large ? 7 : 3);
13689 int32_t l = 10;
13690
13691 for (int32_t y = 0; y < 8; y++)
13692 {
13693 // Users might have set the dmap to a map that has since been deleted.
13694 if (themap >= Map.getMapCount())
13695 break;
13696
13697 for (int32_t x = 0; x < cols; x++)
13698 {
13699 if (x + xoff < 0 || x + xoff > 15)
13700 continue;
13701
13702 const mapscr* scr = get_canonical_scr(themap, y * 16 + x + (large ? xoff : 0));
13703 if (!(scr->valid & mVALID))
13704 continue;
13705
13706 al_draw_filled_rectangle(dx + (x * col_width), dy + (y * l), dx + (x * col_width + col_width), dy + ((y * l) + l), real_lc1(scr->color));
13707 al_draw_filled_rectangle(dx + (x * col_width + dot_offset), dy + (y * l + 3), dx + (x * col_width + dot_offset + dot_width), dy + (y * l + l - 3), real_lc2(scr->color));
13708 }
13709 }
13710
13711 al_restore_state(&old_state);
13712 }
13713
13714 12 ListData dmap_list(dmaplist, &font);
13715
13716 12 static dmap copiedDMap;
13717 static byte dmapcopied = 0;
13718
13719 int32_t writesomedmaps(PACKFILE *f, int32_t first, int32_t last, int32_t max)
13720 {
13721
13722 dword section_version=V_DMAPS;
13723 int32_t zversion = ZELDA_VERSION;
13724 int32_t zbuild = VERSION_BUILD;
13725
13726 if(!p_iputl(V_ZDMAP,f))
13727 {
13728 return 0;
13729 }
13730
13731 //section version info
13732 if(!p_iputl(zversion,f))
13733 {
13734 return 0;
13735 }
13736 if(!p_iputl(zbuild,f))
13737 {
13738 return 0;
13739 }
13740 if(!p_iputw(section_version,f))
13741 {
13742 new_return(2);
13743 }
13744
13745 if(!write_deprecated_section_cversion(section_version, f))
13746 {
13747 new_return(3);
13748 }
13749 //max possible at this time
13750 if(!p_iputl(max,f))
13751 {
13752 new_return(4);
13753 }
13754 //first id written
13755 if(!p_iputl(first,f))
13756 {
13757 new_return(5);
13758 }
13759 //last id written
13760 if(!p_iputl(last,f))
13761 {
13762 new_return(6);
13763 }
13764 int32_t count = last-first;
13765 //number written
13766 if(!p_iputl(count,f))
13767 {
13768 new_return(7);
13769 }
13770
13771
13772 for ( int32_t i = first; i <= last; ++i )
13773 {
13774 if ( i > max ) break;
13775
13776 if (int ret = write_one_dmap(f, i))
13777 return ret;
13778 }
13779
13780 return 1;
13781 }
13782
13783 int32_t readsomedmaps(PACKFILE *f)
13784 {
13785 dword section_version = 0;
13786 int32_t zversion = 0;
13787 int32_t zbuild = 0;
13788 dmap tempdmap{};
13789
13790 int32_t first = 0, last = 0, max = 0, count = 0;
13791 int32_t datatype_version = 0;
13792
13793 //char dmapstring[64]={0};
13794 //section version info
13795 if(!p_igetl(&datatype_version,f))
13796 {
13797 return 0;
13798 }
13799 if ( datatype_version < 0 )
13800 {
13801 if(!p_igetl(&zversion,f))
13802 {
13803 return 0;
13804 }
13805 }
13806 else
13807 {
13808 zversion = datatype_version;
13809 }
13810 if(!p_igetl(&zbuild,f))
13811 {
13812 return 0;
13813 }
13814
13815 if(!p_igetw(&section_version,f))
13816 {
13817 return 0;
13818 }
13819
13820 if(!read_deprecated_section_cversion(f))
13821 {
13822 return 0;
13823 }
13824 if ( datatype_version < 0 )
13825 {
13826 if(!p_igetl(&max,f))
13827 {
13828 return 0;
13829 }
13830 if(!p_igetl(&first,f))
13831 {
13832 return 0;
13833 }
13834 if(!p_igetl(&last,f))
13835 {
13836 return 0;
13837 }
13838 if(!p_igetl(&count,f))
13839 {
13840 return 0;
13841 }
13842 }
13843 else
13844 {
13845 first = 0;
13846 last = 0;
13847 count = 1;
13848 max = 255;
13849 }
13850
13851
13852
13853
13854 al_trace("readsomedmaps section_version: %d\n", section_version);
13855
13856 if ( zversion > ZELDA_VERSION )
13857 {
13858 al_trace("Cannot read .zdmap packfile made in ZC version (%x) in this version of ZC (%x)\n", zversion, ZELDA_VERSION);
13859 return 0;
13860 }
13861 else if (( section_version > V_DMAPS ))
13862 {
13863 al_trace("Cannot read .zdmap packfile made using V_DMAPS (%d)\n", section_version);
13864 return 0;
13865 }
13866 else
13867 {
13868 al_trace("Reading a .zdmap packfile made in ZC Version: %x, Build: %d\n", zversion, zbuild);
13869 }
13870 //if(!pfread(&dmapstring, 64, f))
13871 //{
13872 // return 0;
13873 //}
13874 for ( int32_t i = first; i <= last; ++i )
13875 {
13876 if (int ret = read_one_dmap(f, &header, section_version, i))
13877 return ret;
13878 }
13879 return 1;
13880 }
13881
13882 int32_t onDmaps()
13883 {
13884 DMapListerDialog(0).show();
13885 return D_O_K;
13886 }
13887
13888 int32_t onMaps()
13889 {
13890 call_edit_map_settings(Map.getCurrMap());
13891 return D_O_K;
13892 }
13893
13894 int32_t onMusic()
13895 {
13896 stopMusic();
13897 call_music_dialog();
13898 return D_O_K;
13899 }
13900 int32_t onMidis()
13901 {
13902 stopMusic();
13903 MidiListerDialog().show();
13904 return D_O_K;
13905 }
13906
13907 const char *warptypelist(int32_t index, int32_t *list_size)
13908 {
13909 if(index>=0)
13910 {
13911 if(index>=MAXWARPTYPES)
13912 index=MAXWARPTYPES-1;
13913
13914 return warptype_string[index];
13915 }
13916
13917 *list_size=MAXWARPTYPES;
13918 // *list_size=6;
13919 return NULL;
13920 }
13921
13922 const char *warpeffectlist(int32_t index, int32_t *list_size)
13923 {
13924 if(index>=0)
13925 {
13926 if(index>=MAXWARPEFFECTS)
13927 index=MAXWARPEFFECTS-1;
13928
13929 return warpeffect_string[index];
13930 }
13931
13932 *list_size=MAXWARPEFFECTS;
13933 return NULL;
13934 }
13935
13936 static int32_t warp1_list[] =
13937 {
13938 2,3,4,5,6,7,8,9,10,11,12,13,53,54,63,67,-1
13939 };
13940
13941 static int32_t warp2_list[] =
13942 {
13943 17,18,19,20,21,22,23,24,25,26,27,28,55,56,64,68,-1
13944 };
13945
13946 static int32_t warp3_list[] =
13947 {
13948 29,30,31,32,33,34,35,36,37,38,39,40,57,58,65,69,-1
13949 };
13950
13951 static int32_t warp4_list[] =
13952 {
13953 41,42,43,44,45,46,47,48,49,50,51,52,59,60,66,70,-1
13954 };
13955
13956 static TABPANEL warp_tabs[] =
13957 {
13958 // (text)
13959 { (char *)"A", D_SELECTED, warp1_list, 0, NULL },
13960 { (char *)"B", 0, warp2_list, 0, NULL },
13961 { (char *)"C", 0, warp3_list, 0, NULL },
13962 { (char *)"D", 0, warp4_list, 0, NULL },
13963 { NULL, 0, NULL, 0, NULL }
13964 };
13965
13966 int32_t onTileWarpIndex(int32_t index)
13967 {
13968 int32_t i=-1;
13969
13970 while(warp_tabs[++i].text != NULL)
13971 warp_tabs[i].flags = (i==index ? D_SELECTED : 0);
13972
13973 onTileWarp();
13974 return D_O_K;
13975 }
13976
13977 static char warpr_buf[10];
13978 const char *warprlist(int32_t index, int32_t *list_size)
13979 {
13980 if(index>=0)
13981 {
13982 bound(index,0,3);
13983 sprintf(warpr_buf,"%c",index+0x41);
13984 return warpr_buf;
13985 }
13986
13987 *list_size=4;
13988 return NULL;
13989 }
13990
13991 int32_t d_wflag_proc(int32_t msg,DIALOG *d,int32_t c);
13992
13993 12 static ListData warp_dlg_list(warptypelist, &font);
13994 12 static ListData warp_ret_list(warprlist, &font);
13995
13996 int32_t d_warpdestscrsel_proc(int32_t msg,DIALOG *d,int32_t c)
13997 {
13998 if(msg == MSG_START)
13999 {
14000 d->d1 = -1; //cached val
14001 d->d2 = -1; //cached dmap
14002 d->fg = 0; //cached 'force_16'
14003 }
14004 char* buf = (char*)d->dp;
14005 vector<DIALOG*>* dlgs = (vector<DIALOG*>*)d->dp2;
14006 int* dmap_ptr = (int*) d->dp3;
14007 if(!(buf && dmap_ptr))
14008 return D_O_K;
14009 bool is_overworld = ((DMaps[*dmap_ptr].type&dmfTYPE)==dmOVERW);
14010 int scrw = is_overworld ? 16 : 8, scrh = 9;
14011 const int max = 0x87;
14012 int bufval = zc_xtoi(buf);
14013 int val = vbound(bufval,0,max);
14014 auto& dm = DMaps[*dmap_ptr];
14015 auto val_offset = dm.xoff < 0 ? -dm.xoff : 0;
14016 bool force_16 = d->fg;
14017 if(!is_overworld)
14018 {
14019 if((val&0xF) >= 0x8)
14020 force_16 = true;
14021 else if((val&0xF) < val_offset && (val&0xF0) < 0x80)
14022 force_16 = true;
14023 }
14024 if(force_16) //can't bound, some quests need to warp out of bounds... -Em
14025 {
14026 scrw = 16; //just force show the larger grid instead
14027 val_offset = 0;
14028 }
14029
14030 int xscl = d->w/scrw;
14031 int yscl = d->h/scrh;
14032
14033 int ret = D_O_K;
14034 bool redraw = false;
14035 if(d->d1 != val)
14036 {
14037 redraw = true;
14038 d->d1 = val;
14039 }
14040 if(bufval != val)
14041 {
14042 redraw = true;
14043 sprintf(buf, "%X", val);
14044 }
14045 if(d->d2 != *dmap_ptr)
14046 {
14047 redraw = true;
14048 d->d2 = *dmap_ptr;
14049 }
14050 switch(msg)
14051 {
14052 case MSG_WANTFOCUS:
14053 ret = D_WANTFOCUS;
14054 break;
14055 case MSG_CLICK:
14056 {
14057 d->fg = force_16 ? 1 : 0;
14058 bool redraw2 = false;
14059 while(gui_mouse_b())
14060 {
14061 if(redraw2)
14062 {
14063 broadcast_dialog_message(MSG_DRAW, 0);
14064 redraw2 = false;
14065 }
14066 if(!d->fg && (gui_mouse_b()&2))
14067 {
14068 scrw = 16;
14069 xscl = d->w/scrw;
14070 yscl = d->h/scrh;
14071 val_offset = 0;
14072 d->fg = 1;
14073 redraw2 = true;
14074 }
14075 custom_vsync();
14076 if(!mouse_in_rect(d->x,d->y,d->w,d->h))
14077 continue;
14078 int mx = gui_mouse_x()-d->x, my = gui_mouse_y()-d->y;
14079 int y = vbound(my/yscl,0,scrh-1);
14080 auto offs = y==8 ? 0 : val_offset;
14081 int x = vbound(mx/xscl,offs,scrw-1);
14082 auto val2 = (y*16)+x;
14083 if(val2 > max) //out of bounds in the bottom-right
14084 continue;
14085 val = val2;
14086 if(d->d1 != val)
14087 {
14088 d->d1 = val;
14089 sprintf(buf, "%02X", val);
14090 redraw2 = true;
14091 }
14092 }
14093 redraw = true;
14094 d->fg = 0;
14095 break;
14096 }
14097 case MSG_DRAW:
14098 {
14099 rectfill(screen,d->x,d->y,d->x+d->w-1,d->y+d->h-1,jwin_pal[jcBOX]);
14100 jwin_draw_frame(screen, d->x-2, d->y-2, d->w+4, d->h+4, FR_MENU);
14101 for(int yind = 0; yind < scrh; ++yind)
14102 {
14103 auto gr = (yind < 8 ? dm.grid[yind] : 0);
14104 for(int xind = (yind == 8 ? 0 : val_offset); xind < scrw; ++xind)
14105 {
14106 int screen_index = xind+(yind*16);
14107 if(screen_index > max)
14108 continue;
14109 int fr = FR_MENU;
14110 if(screen_index == d->d1)
14111 fr = FR_GREEN;
14112 else if(!is_overworld && xind < 8 && (gr&(1<<(8-xind-1))))
14113 fr = FR_MENU_INV;
14114 jwin_draw_frame(screen, d->x+(xind*xscl), d->y+(yind*yscl), xscl, yscl, fr);
14115 }
14116 }
14117 break;
14118 }
14119 case MSG_XCHAR:
14120 {
14121 bool on_80 = (val&0xF0) == 0x80;
14122 switch(c>>8)
14123 {
14124 case KEY_UP:
14125 if((val&0xF0) && !(val_offset && on_80 && (val&0xF) < val_offset))
14126 {
14127 val -= 0x10;
14128 redraw = true;
14129 }
14130 ret |= D_USED_CHAR;
14131 break;
14132 case KEY_DOWN:
14133 if((val&0xF0) < ((val&0xF) < 0x8 ? 0x80 : 0x70))
14134 {
14135 val += 0x10;
14136 redraw = true;
14137 }
14138 ret |= D_USED_CHAR;
14139 break;
14140 case KEY_LEFT:
14141 if((val&0xF) > (on_80 ? 0 : val_offset))
14142 {
14143 --val;
14144 redraw = true;
14145 }
14146 ret |= D_USED_CHAR;
14147 break;
14148 case KEY_RIGHT:
14149 if((val&0xF) < scrw-1 && val < 0x87)
14150 {
14151 ++val;
14152 redraw = true;
14153 }
14154 ret |= D_USED_CHAR;
14155 break;
14156 }
14157 if(redraw)
14158 sprintf(buf, "%02X", val);
14159 break;
14160 }
14161 }
14162 if(redraw)
14163 {
14164 if(msg == MSG_IDLE)
14165 broadcast_dialog_message(MSG_DRAW,0);
14166 else
14167 {
14168 d->d1 = d->d2 = -1;
14169 object_message(d,MSG_IDLE,0);
14170 }
14171 }
14172
14173 return ret;
14174 }
14175
14176 int32_t tilewarpdmapxy[6] = {170,38,170,18,170,27};
14177 static DIALOG tilewarp_dlg[] =
14178 {
14179 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
14180 12 { jwin_win_proc, 0, 0, 302, 178, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
14181 12 { jwin_rtext_proc, 89, 43, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Type:", NULL, NULL },
14182 12 { jwin_rtext_proc, 57, 62, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "DMap:", NULL, NULL },
14183 12 { jwin_rtext_proc, 57, 80, 64, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Screen: 0x", NULL, NULL },
14184 12 { jwin_droplist_proc, 91, 38, 193, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &warp_dlg_list, NULL, NULL },
14185 //5
14186 12 { d_dropdmaplist_proc, 59, 57, 225, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &dmap_list, NULL, tilewarpdmapxy },
14187 12 { jwin_hexedit_proc, 59, 76, 24, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
14188 12 { jwin_button_proc, 61, 152, 41, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
14189 12 { jwin_button_proc, 121, 152, 41, 21, vc(14), vc(1), 'g', D_EXIT, 0, 0, (void *) "&Go", NULL, NULL },
14190 12 { jwin_button_proc, 181, 152, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14191 //10
14192 12 { jwin_rtext_proc, 82, 95, 100, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Use Warp Return:", NULL, NULL },
14193 12 { jwin_droplist_proc, 10, 105, 72, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &warp_ret_list, NULL, NULL },
14194 12 { jwin_check_proc, 10, 125, 129, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Combos Carry Over", NULL, NULL },
14195 12 { d_warpdestscrsel_proc, 90, 76, 8*16, 8*9, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14196 12 { jwin_button_proc, 59, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "A", NULL, NULL },
14197 //15
14198 12 { jwin_button_proc, 109, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "B", NULL, NULL },
14199 12 { jwin_button_proc, 159, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "C", NULL, NULL },
14200 12 { jwin_button_proc, 209, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "D", NULL, NULL },
14201 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14202 };
14203
14204 int32_t sidewarpdmapxy[6] = {170,38,170,18,170,27};
14205 static DIALOG sidewarp_dlg[] =
14206 {
14207 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
14208 12 { jwin_win_proc, 0, 0, 302, 178, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
14209 12 { jwin_rtext_proc, 89, 43, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Type:", NULL, NULL },
14210 12 { jwin_rtext_proc, 57, 62, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "DMap:", NULL, NULL },
14211 12 { jwin_rtext_proc, 57, 80, 64, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Screen: 0x", NULL, NULL },
14212 12 { jwin_droplist_proc, 91, 38, 193, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &warp_dlg_list, NULL, NULL },
14213 //5
14214 12 { d_dropdmaplist_proc, 59, 57, 225, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &dmap_list, NULL, tilewarpdmapxy },
14215 12 { jwin_hexedit_proc, 59, 76, 24, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
14216 12 { jwin_button_proc, 61, 152, 41, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
14217 12 { jwin_button_proc, 121, 152, 41, 21, vc(14), vc(1), 'g', D_EXIT, 0, 0, (void *) "&Go", NULL, NULL },
14218 12 { jwin_button_proc, 181, 152, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14219 //10
14220 12 { jwin_rtext_proc, 82, 95, 100, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Use Warp Return:", NULL, NULL },
14221 12 { jwin_droplist_proc, 10, 105, 72, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &warp_ret_list, NULL, NULL },
14222 12 { jwin_check_proc, 10, 125, 129, 9, vc(14), vc(1), 0, 0, 1, 0, (void *) "Combos Carry Over", NULL, NULL },
14223 12 { d_warpdestscrsel_proc, 90, 76, 8*16, 8*9, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14224 12 { jwin_button_proc, 59, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "A", NULL, NULL },
14225 //15
14226 12 { jwin_button_proc, 109, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "B", NULL, NULL },
14227 12 { jwin_button_proc, 159, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "C", NULL, NULL },
14228 12 { jwin_button_proc, 209, 21, 50, 14, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "D", NULL, NULL },
14229 // 18
14230 12 { d_wflag_proc, 18, 17, 15, 8, vc(4), vc(0), 0, 0, 1, 0, NULL, NULL, NULL },
14231 12 { d_wflag_proc, 18, 47, 15, 8, vc(4), vc(0), 0, 0, 1, 0, NULL, NULL, NULL },
14232 // 20
14233 12 { d_wflag_proc, 8, 27, 8, 15, vc(4), vc(0), 0, 0, 1, 0, NULL, NULL, NULL },
14234 12 { d_wflag_proc, 37, 27, 8, 15, vc(4), vc(0), 0, 0, 1, 0, NULL, NULL, NULL },
14235
14236 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14237 };
14238
14239 int32_t warpringxy[6] = {170,38,170,18,170,27};
14240 static DIALOG warpring_warp_dlg[] =
14241 {
14242 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
14243 12 { jwin_win_proc, 0, 0, 302, 145, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
14244 12 { jwin_rtext_proc, 57, 25, 40, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "DMap:", NULL, NULL },
14245 12 { jwin_rtext_proc, 57, 46, 64, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Screen: 0x", NULL, NULL },
14246 12 { d_dropdmaplist_proc, 59, 19, 225, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &dmap_list, NULL, warpringxy },
14247 12 { jwin_hexedit_proc, 59, 39, 24, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
14248 // 5
14249 12 { jwin_button_proc, 61, 115, 41, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
14250 12 { jwin_button_proc, 121, 115, 41, 21, vc(14), vc(1), 'g', D_EXIT, 0, 0, (void *) "&Go", NULL, NULL },
14251 12 { jwin_button_proc, 181, 115, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14252 12 { d_warpdestscrsel_proc, 90, 39, 8*16, 8*9, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14253
14254 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14255 };
14256
14257 // Side warp flag procedure
14258 int32_t d_wflag_proc(int32_t msg,DIALOG *d,int32_t)
14259 {
14260 int32_t ret = D_O_K;
14261 switch(msg)
14262 {
14263 case MSG_DRAW:
14264 {
14265 int32_t c2=(d->flags&D_SELECTED)?d->fg:d->bg;
14266
14267 if(d->d1==1)
14268 {
14269 jwin_draw_frame(screen,d->x,d->y,d->w,d->h, FR_DEEP);
14270 rectfill(screen,d->x+2, d->y+2, d->x+d->w-3, d->y+d->h-3,c2);
14271
14272 if(d->flags&D_SELECTED)
14273 {
14274 int32_t e=d->d2&3;
14275
14276 if(d->w>d->h)
14277 textprintf_centre_ex(screen,get_zc_font(font_lfont_l), d->x+(d->w/2),d->y,jwin_pal[jcBOXFG],-1,"%c",e+0x41);
14278 else
14279 textprintf_centre_ex(screen,get_zc_font(font_lfont_l), d->x+(d->w/2),d->y+(d->h/2)-4,jwin_pal[jcBOXFG],-1,"%c",e+0x41);
14280 }
14281
14282 }
14283 else
14284 {
14285 rectfill(screen,d->x, d->y, d->x+d->w-1, d->y+d->h-1,c2);
14286 }
14287 }
14288 break;
14289
14290 case MSG_CLICK:
14291 {
14292 if(d->flags & D_DISABLED)
14293 return D_O_K;
14294 bool rclick = gui_mouse_b() & 2;
14295 if(d->d1==1)
14296 {
14297 if(!(d->flags&D_SELECTED))
14298 {
14299 d->flags |= D_SELECTED;
14300 d->d2 &= 0x80;
14301 if (rclick)
14302 d->d2 |= 3;
14303 }
14304 else
14305 {
14306 if((d->d2&3) == (rclick?0:3))
14307 {
14308 d->flags ^= D_SELECTED;
14309 d->d2 &= 0x80;
14310 }
14311 else
14312 {
14313 int32_t f = d->d2&3;
14314 d->d2 &= 0x80;
14315 f += rclick ? -1 : 1;
14316 d->d2 |= f;
14317 }
14318 }
14319 }
14320 else
14321 {
14322 d->flags^=D_SELECTED;
14323 }
14324
14325 int32_t c2=(d->flags&D_SELECTED)?d->fg:d->bg;
14326
14327 if(d->d1==1)
14328 {
14329 jwin_draw_frame(screen,d->x,d->y,d->w,d->h, FR_DEEP);
14330 rectfill(screen,d->x+2, d->y+2, d->x+d->w-3, d->y+d->h-3,c2);
14331
14332 if(d->flags&D_SELECTED)
14333 {
14334 int32_t e=d->d2&3;
14335
14336 if(d->w>d->h)
14337 textprintf_centre_ex(screen,get_zc_font(font_lfont_l),d->x+(d->w/2),d->y,jwin_pal[jcBOXFG],-1,"%c",e+0x41);
14338 else
14339 textprintf_centre_ex(screen,get_zc_font(font_lfont_l),d->x+(d->w/2),d->y+(d->h/2)-4,jwin_pal[jcBOXFG],-1,"%c",e+0x41);
14340 }
14341 }
14342 else
14343 {
14344 rectfill(screen,d->x, d->y, d->x+d->w-1, d->y+d->h-1,c2);
14345 }
14346
14347
14348 while(gui_mouse_b())
14349 {
14350 /* do nothing */
14351 rest(1);
14352 }
14353 ret = D_REDRAWME;
14354 }
14355 break;
14356 }
14357
14358 return ret;
14359 }
14360
14361 int32_t d_dmapscrsel_proc(int32_t msg,DIALOG *d,int32_t c)
14362 {
14363 //these are here to bypass compiler warnings about unused arguments
14364 c=c;
14365
14366 int32_t ret = D_O_K;
14367
14368 switch(msg)
14369 {
14370 case MSG_CLICK:
14371 sprintf((char*)((d+2)->dp),"%X%X",vbound((gui_mouse_y()-d->y)/4,0,7),vbound((gui_mouse_x()-d->x)/(((DMaps[(d-1)->d1].type&dmfTYPE)==1)?4:8),0,(((DMaps[(d-1)->d1].type&dmfTYPE)==1)?15:7)));
14372 object_message(d+2, MSG_DRAW, 0);
14373 break;
14374 }
14375
14376 return ret;
14377 }
14378
14379 int32_t warpdestsel_x=-1;
14380 int32_t warpdestsel_y=-1;
14381 int32_t warpdestmap=-1;
14382 int32_t warpdestscr=-1;
14383
14384 int32_t jwin_minibutton_proc(int32_t msg,DIALOG *d,int32_t c)
14385 {
14386 switch(msg)
14387 {
14388 case MSG_DRAW:
14389 jwin_draw_text_button(screen, d->x, d->y, d->w, d->h, (char*)d->dp, d->flags, false);
14390 return D_O_K;
14391 break;
14392 }
14393
14394 return jwin_button_proc(msg,d,c);
14395 }
14396
14397 int32_t d_triggerbutton_proc(int32_t msg,DIALOG *d,int32_t c)
14398 {
14399 static BITMAP *dummy=create_bitmap_ex(8, 1, 1);
14400
14401 switch(msg)
14402 {
14403 case MSG_START:
14404 d->w=gui_textout_ln(dummy, font, (uint8_t *)d->dp, 0, 0, jwin_pal[jcMEDDARK], -1, 0)+4;
14405 d->h=text_height(font)+5;
14406 break;
14407
14408 case MSG_GOTFOCUS:
14409 d->flags&=~D_GOTFOCUS;
14410 break;
14411
14412 }
14413
14414 return jwin_minibutton_proc(msg,d,c);
14415 }
14416
14417 int32_t d_alltriggerbutton_proc(int32_t msg,DIALOG *d,int32_t c)
14418 {
14419 DIALOG *temp_d;
14420 int32_t ret=d_triggerbutton_proc(msg,d,c);
14421
14422 switch(msg)
14423 {
14424 case MSG_CLICK:
14425 temp_d=d-1;
14426
14427 while(temp_d->proc==d_triggerbutton_proc)
14428 {
14429 temp_d->flags&=~D_SELECTED;
14430 temp_d->flags|=D_DIRTY;
14431
14432 if(d->flags&D_SELECTED)
14433 {
14434 temp_d->flags|=D_SELECTED;
14435 }
14436
14437 --temp_d;
14438 }
14439
14440 break;
14441 }
14442
14443 return ret;
14444 }
14445
14446 int32_t d_ticsedit_proc(int32_t msg,DIALOG *d,int32_t c)
14447 {
14448 int32_t ret = jwin_edit_proc(msg,d,c);
14449
14450 if(msg==MSG_DRAW)
14451 {
14452 int32_t tics=vbound(atoi((char*)d->dp),0,65535);
14453 sprintf((char*)(d+1)->dp,"%s %s",ticksstr(tics),tics==0?"(No Timed Warp)":" ");
14454 object_message(d+1,MSG_DRAW,c);
14455 }
14456
14457 return ret;
14458 }
14459
14460 12 static ListData warp_effect_list(warpeffectlist,&font);
14461
14462 struct tw_data
14463 {
14464 int twscr[4], twtype[4], twdmap[4], wret[4];
14465 byte oflags;
14466 optional<uint> loaded;
14467
14468 tw_data(mapscr* scr) {load_scr(scr);}
14469 void load_scr(mapscr* scr)
14470 {
14471 oflags = scr->tilewarpoverlayflags;
14472 for(int q = 0; q < 4; ++q)
14473 {
14474 twscr[q] = scr->tilewarpscr[q];
14475 twtype[q] = scr->tilewarptype[q];
14476 twdmap[q] = scr->tilewarpdmap[q];
14477 wret[q] = (scr->warpreturnc >> (2*q))&3;
14478 }
14479 loaded.reset();
14480 }
14481 void save_scr(mapscr* scr)
14482 {
14483 mark_save_dirty();
14484 scr->tilewarpoverlayflags = oflags;
14485 scr->warpreturnc = scr->warpreturnc & 0xFF00;
14486 for(int q = 0; q < 4; ++q)
14487 {
14488 scr->tilewarpscr[q] = twscr[q];
14489 scr->tilewarptype[q] = twtype[q];
14490 scr->tilewarpdmap[q] = twdmap[q];
14491 scr->warpreturnc |= wret[q] << (2*q);
14492 }
14493 }
14494
14495 void load(uint ind)
14496 {
14497 if(ind >= 4) return;
14498 loaded = ind;
14499 tilewarp_dlg[4].d1 = twtype[ind];
14500 tilewarp_dlg[5].d1 = twdmap[ind];
14501 char* buf = (char*)tilewarp_dlg[6].dp;
14502 sprintf(buf,"%02X",twscr[ind]);
14503 tilewarp_dlg[11].d1 = wret[ind];
14504 SETFLAG(tilewarp_dlg[12].flags, D_SELECTED, get_bit(&oflags,ind));
14505 for(int q = 0; q < 4; ++q)
14506 SETFLAG(tilewarp_dlg[14+q].flags,(D_SELECTED|D_DISABLED),q==ind);
14507 }
14508 void save(uint ind)
14509 {
14510 if(ind >= 4) return;
14511 twtype[ind] = tilewarp_dlg[4].d1;
14512 twdmap[ind] = tilewarp_dlg[5].d1;
14513 char* buf = (char*)tilewarp_dlg[6].dp;
14514 twscr[ind] = vbound(zc_xtoi(buf),0x00,0x87);
14515 wret[ind] = tilewarp_dlg[11].d1;
14516 set_bit(&oflags, ind, tilewarp_dlg[12].flags & D_SELECTED);
14517 }
14518 void save()
14519 {
14520 if(loaded)
14521 save(*loaded);
14522 }
14523 void swap(uint ind)
14524 {
14525 if(ind >= 4) return;
14526 if(loaded)
14527 {
14528 save(*loaded);
14529 if(*loaded == ind)
14530 return;
14531 }
14532 load(ind);
14533 }
14534 };
14535 int32_t onTileWarp()
14536 {
14537 restore_mouse();
14538 tilewarp_dlg[0].dp=(void *) "Tile Warp";
14539 tilewarp_dlg[0].dp2=get_zc_font(font_lfont);
14540
14541 mapscr* mptr = Map.CurrScr();
14542 char buf[10];
14543 tilewarp_dlg[6].dp=buf;
14544 tilewarp_dlg[13].dp = buf;
14545 tilewarp_dlg[13].dp3 = &tilewarp_dlg[5].d1;
14546
14547 vector<DIALOG*> dlgs;
14548 dlgs.push_back(&tilewarp_dlg[5]);
14549 dlgs.push_back(&tilewarp_dlg[6]);
14550 tilewarp_dlg[13].dp2 = &dlgs;
14551
14552 tw_data data(mptr);
14553 data.load(0);
14554
14555 dmap_list_size=MAXDMAPS;
14556 dmap_list_zero=true;
14557
14558 large_dialog(tilewarp_dlg);
14559
14560 bool running = true;
14561 int ret;
14562 do
14563 {
14564 ret = do_zqdialog(tilewarp_dlg,-1);
14565 switch(ret)
14566 {
14567 // OK, GO
14568 case 7: case 8:
14569 running = false;
14570 data.save();
14571 data.save_scr(mptr);
14572 refresh(rMENU);
14573 break;
14574 //Cancel
14575 case 9:
14576 running = false;
14577 break;
14578 //A,B,C,D
14579 case 14: case 15: case 16: case 17:
14580 data.swap(ret-14);
14581 break;
14582 }
14583 }
14584 while(running);
14585
14586 if(ret==8) //GO
14587 {
14588 int32_t index = *data.loaded;
14589
14590 FlashWarpSquare = -1;
14591 int32_t tm = Map.getCurrMap();
14592 int32_t ts = Map.getCurrScr();
14593 int32_t thistype = mptr->tilewarptype[index];
14594 Map.dowarp(0,index);
14595
14596 if((ts!=Map.getCurrScr() || tm!=Map.getCurrMap()) && thistype != wtCAVE && thistype != wtSCROLL)
14597 {
14598 FlashWarpSquare = (TheMaps[tm*MAPSCRS+ts].warpreturnc>>(index*2))&3;
14599 FlashWarpClk = 32;
14600 }
14601
14602 refresh(rALL);
14603 }
14604
14605 return D_O_K;
14606 }
14607
14608 struct sw_data
14609 {
14610 int swscr[4], swtype[4], swdmap[4], wret[4];
14611 byte oflags;
14612 optional<uint> loaded;
14613
14614 sw_data(mapscr* scr) {load_scr(scr);}
14615 void load_scr(mapscr* scr)
14616 {
14617 oflags = scr->sidewarpoverlayflags;
14618 for(int q = 0; q < 4; ++q)
14619 {
14620 swscr[q] = scr->sidewarpscr[q];
14621 swtype[q] = scr->sidewarptype[q];
14622 swdmap[q] = scr->sidewarpdmap[q];
14623 wret[q] = (scr->warpreturnc >> (2*(q+4)))&3;
14624 }
14625 loaded.reset();
14626
14627 for(int32_t i=0; i<4; i++)
14628 {
14629 sidewarp_dlg[18+i].d2 = 0x80;
14630 if(scr->flags2&(1<<i))
14631 {
14632 sidewarp_dlg[18+i].flags = D_SELECTED ;
14633 sidewarp_dlg[18+i].d2 |= (scr->sidewarpindex>>(2*i))&3;
14634 }
14635 else
14636 {
14637 sidewarp_dlg[18+i].flags = 0;
14638 }
14639 }
14640 }
14641 void save_scr(mapscr* scr)
14642 {
14643 mark_save_dirty();
14644 scr->sidewarpoverlayflags = oflags;
14645 scr->warpreturnc = scr->warpreturnc & 0x00FF;
14646 for(int q = 0; q < 4; ++q)
14647 {
14648 scr->sidewarpscr[q] = swscr[q];
14649 scr->sidewarptype[q] = swtype[q];
14650 scr->sidewarpdmap[q] = swdmap[q];
14651 scr->warpreturnc |= wret[q] << (2*(q+4));
14652 }
14653
14654 scr->flags2 &= ~0xF;
14655 scr->sidewarpindex = 0;
14656 for(int32_t i=0; i<4; i++)
14657 {
14658 if(sidewarp_dlg[18+i].flags & D_SELECTED)
14659 scr->flags2 |= 1<<i;
14660 scr->sidewarpindex |= (sidewarp_dlg[18+i].d2&3) << (i*2);
14661 }
14662 }
14663
14664 void load(uint ind)
14665 {
14666 if(ind >= 4) return;
14667 loaded = ind;
14668 sidewarp_dlg[4].d1 = swtype[ind];
14669 sidewarp_dlg[5].d1 = swdmap[ind];
14670 char* buf = (char*)sidewarp_dlg[6].dp;
14671 sprintf(buf,"%02X",swscr[ind]);
14672 sidewarp_dlg[11].d1 = wret[ind];
14673 SETFLAG(sidewarp_dlg[12].flags, D_SELECTED, get_bit(&oflags,ind));
14674 for(int q = 0; q < 4; ++q)
14675 SETFLAG(sidewarp_dlg[14+q].flags,(D_SELECTED|D_DISABLED),q==ind);
14676 }
14677 void save(uint ind)
14678 {
14679 if(ind >= 4) return;
14680 swtype[ind] = sidewarp_dlg[4].d1;
14681 swdmap[ind] = sidewarp_dlg[5].d1;
14682 char* buf = (char*)sidewarp_dlg[6].dp;
14683 swscr[ind] = vbound(zc_xtoi(buf),0x00,0x87);
14684 wret[ind] = sidewarp_dlg[11].d1;
14685 set_bit(&oflags, ind, sidewarp_dlg[12].flags & D_SELECTED);
14686 }
14687 void save()
14688 {
14689 if(loaded)
14690 save(*loaded);
14691 }
14692 void swap(uint ind)
14693 {
14694 if(ind >= 4) return;
14695 if(loaded)
14696 {
14697 save(*loaded);
14698 if(*loaded == ind)
14699 return;
14700 }
14701 load(ind);
14702 }
14703 };
14704 int32_t onSideWarp()
14705 {
14706 restore_mouse();
14707 sidewarp_dlg[0].dp=(void *) "Side Warp";
14708 sidewarp_dlg[0].dp2=get_zc_font(font_lfont);
14709
14710 mapscr* mptr = Map.CurrScr();
14711 char buf[10];
14712 sidewarp_dlg[6].dp=buf;
14713 sidewarp_dlg[13].dp = buf;
14714 sidewarp_dlg[13].dp3 = &sidewarp_dlg[5].d1;
14715
14716 vector<DIALOG*> dlgs;
14717 dlgs.push_back(&sidewarp_dlg[5]);
14718 dlgs.push_back(&sidewarp_dlg[6]);
14719 sidewarp_dlg[13].dp2 = &dlgs;
14720
14721 sw_data data(mptr);
14722 data.load(0);
14723
14724 dmap_list_size=MAXDMAPS;
14725 dmap_list_zero=true;
14726
14727 large_dialog(sidewarp_dlg);
14728
14729 bool running = true;
14730 int ret;
14731 do
14732 {
14733 ret = do_zqdialog(sidewarp_dlg,-1);
14734 switch(ret)
14735 {
14736 // OK, GO
14737 case 7: case 8:
14738 running = false;
14739 data.save();
14740 data.save_scr(mptr);
14741 refresh(rMENU);
14742 break;
14743 //Cancel
14744 case 9:
14745 running = false;
14746 break;
14747 //A,B,C,D
14748 case 14: case 15: case 16: case 17:
14749 data.swap(ret-14);
14750 break;
14751 }
14752 }
14753 while(running);
14754
14755 if(ret==8) //GO
14756 {
14757 int32_t index = *data.loaded;
14758
14759 FlashWarpSquare = -1;
14760 int32_t tm = Map.getCurrMap();
14761 int32_t ts = Map.getCurrScr();
14762
14763 int32_t thistype = mptr->sidewarptype[index];
14764 Map.dowarp(1,index);
14765
14766 if((ts!=Map.getCurrScr() || tm!=Map.getCurrMap()) && thistype != wtSCROLL)
14767 {
14768 FlashWarpSquare = (TheMaps[tm*MAPSCRS+ts].warpreturnc>>(8+index*2))&3;
14769 FlashWarpClk = 0x20;
14770 }
14771
14772 refresh(rALL);
14773 }
14774
14775 return D_O_K;
14776 }
14777
14778
14779
14780 const char *dirlist(int32_t index, int32_t *list_size)
14781 {
14782 if(index>=0)
14783 {
14784 if(index>3)
14785 index=3;
14786
14787 return mazedirstr[index];
14788 }
14789
14790 *list_size=4;
14791 return NULL;
14792 }
14793
14794 12 static ListData path_dlg_list(dirlist, &font);
14795
14796 static const char *wipestr[] = {"None", "Circle", "Oval", "Triangle", "SMAS", "Fade Black"};
14797 // enum {bosCIRCLE=0, bosOVAL, bosTRIANGLE, bosSMAS, bosFADEBLACK, bosMAX};
14798 const char *wipelist(int32_t index, int32_t *list_size)
14799 {
14800 if(index>=0)
14801 {
14802 if(index>5)
14803 index=5;
14804
14805 return wipestr[index];
14806 }
14807
14808 *list_size=6;
14809 return NULL;
14810 }
14811
14812 12 static ListData wipe_effect_dlg_list(wipelist, &font);
14813
14814 static DIALOG path_dlg[] =
14815 {
14816 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
14817 12 { jwin_win_proc, 80, 57, 161, 182, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Maze Path", NULL, NULL },
14818 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14819 12 { jwin_text_proc, 94, 106, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "1st", NULL, NULL },
14820 12 { jwin_text_proc, 94, 124, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "2nd", NULL, NULL },
14821 12 { jwin_text_proc, 94, 142, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "3rd", NULL, NULL },
14822 12 { jwin_text_proc, 94, 160, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "4th", NULL, NULL },
14823 12 { jwin_text_proc, 94, 178, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Exit", NULL, NULL },
14824 12 { jwin_text_proc, 94, 196, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Wipe effect", NULL, NULL },
14825 12 { jwin_droplist_proc, 140, 102, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14826 12 { jwin_droplist_proc, 140, 120, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14827 12 { jwin_droplist_proc, 140, 138, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14828 12 { jwin_droplist_proc, 140, 156, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14829 12 { jwin_droplist_proc, 140, 174, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &path_dlg_list, NULL, NULL },
14830 12 { jwin_droplist_proc, 140, 192, 80+1, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &wipe_effect_dlg_list, NULL, NULL },
14831 12 { jwin_button_proc, 90, 212, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
14832 12 { jwin_button_proc, 170, 212, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14833 12 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *) onHelp, NULL, NULL },
14834 12 { jwin_text_proc, 87, 82, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "A Lost Woods-style maze screen", NULL, NULL },
14835 12 { jwin_text_proc, 87, 92, 192, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "with a normal and secret exit.", NULL, NULL },
14836 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14837 };
14838
14839 int32_t onPath()
14840 {
14841 restore_mouse();
14842 path_dlg[0].dp2=get_zc_font(font_lfont);
14843
14844 for(int32_t i=0; i<4; i++)
14845 path_dlg[i+8].d1 = Map.CurrScr()->path[i];
14846
14847 path_dlg[12].d1 = Map.CurrScr()->exitdir;
14848 path_dlg[13].d1 = Map.CurrScr()->maze_transition_wipe;
14849
14850 large_dialog(path_dlg);
14851
14852 int32_t ret;
14853
14854 do
14855 {
14856 ret=do_zqdialog(path_dlg,8);
14857
14858 if(ret==14)
14859 {
14860 for(int32_t i=0; i<4; i++)
14861 {
14862 if(path_dlg[i+8].d1 == path_dlg[12].d1)
14863 {
14864 if (alert_confirm("Exit Problem","One of the path's directions is also the normal Exit direction! Continue?"))
14865 ret = -1;
14866
14867 break;
14868 }
14869 }
14870 }
14871 }
14872 while(ret == -1);
14873
14874 if(ret==14)
14875 {
14876 mark_save_dirty();
14877
14878 for(int32_t i=0; i<4; i++)
14879 Map.CurrScr()->path[i] = path_dlg[i+8].d1;
14880
14881 Map.CurrScr()->exitdir = path_dlg[12].d1;
14882 Map.CurrScr()->maze_transition_wipe = path_dlg[13].d1;
14883
14884 if(!(Map.CurrScr()->flags&fMAZE))
14885 if (alert_confirm("Screen Flag","Turn on the 'Use Maze Path' Screen Flag?\n(Go to 'Screen Data' to turn it off.)"))
14886 Map.CurrScr()->flags |= fMAZE;
14887 }
14888
14889 refresh(rMAP+rMENU);
14890 return D_O_K;
14891 }
14892
14893
14894
14895 static DIALOG editinfo_dlg[] =
14896 {
14897 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
14898 12 { jwin_win_proc, 0, 10, 208, 204, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
14899 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
14900 12 { jwin_text_proc, 24, 60, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "1st", NULL, NULL },
14901 12 { jwin_text_proc, 24, 106, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "2nd", NULL, NULL },
14902 12 { jwin_text_proc, 24, 152, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "3rd", NULL, NULL },
14903 12 { jwin_text_proc, 56, 60, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
14904 12 { jwin_text_proc, 56, 106, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
14905 12 { jwin_text_proc, 56, 152, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
14906 // 8
14907 12 { jwin_edit_proc, 86, 56, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
14908 12 { d_ndroplist_proc, 56, 74, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
14909 12 { jwin_edit_proc, 86, 102, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
14910 12 { d_ndroplist_proc, 56, 120, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
14911 12 { jwin_edit_proc, 86, 148, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
14912 12 { d_ndroplist_proc, 56, 166, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
14913 12 { jwin_text_proc, 24, 42, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Name:", NULL, NULL },
14914 12 { jwin_edit_proc, 56, 38, 137, 16, vc(12), vc(1), 0, 0, 31, 0, NULL, NULL, NULL },
14915 // 16
14916 12 { jwin_button_proc, 34, 188, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
14917 12 { jwin_button_proc, 114, 188, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
14918 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
14919 };
14920
14921 void EditInfoType(int32_t index)
14922 {
14923 char ps1[6],ps2[6],ps3[6];
14924 char infoname[33];
14925 char caption[40];
14926
14927 int32_t str1, str2, str3;
14928
14929 sprintf(caption,"Info Data %d",index);
14930 editinfo_dlg[0].dp = caption;
14931 editinfo_dlg[0].dp2 = get_zc_font(font_lfont);
14932
14933 sprintf(ps1,"%d",QMisc.info[index].price[0]);
14934 sprintf(ps2,"%d",QMisc.info[index].price[1]);
14935 sprintf(ps3,"%d",QMisc.info[index].price[2]);
14936 strncpy(infoname,QMisc.info[index].name,32);
14937 infoname[32] = 0;
14938 editinfo_dlg[8].dp = ps1;
14939 editinfo_dlg[10].dp = ps2;
14940 editinfo_dlg[12].dp = ps3;
14941 editinfo_dlg[15].dp = infoname;
14942 str1 = QMisc.info[index].str[0];
14943 str2 = QMisc.info[index].str[1];
14944 str3 = QMisc.info[index].str[2];
14945 editinfo_dlg[9].d1 = MsgStrings[str1].listpos;
14946 editinfo_dlg[11].d1 = MsgStrings[str2].listpos;
14947 editinfo_dlg[13].d1 = MsgStrings[str3].listpos;
14948 ListData msgs_list(msgslist2, &a4fonts[font_lfont_l]);
14949 editinfo_dlg[9].dp =
14950 editinfo_dlg[11].dp =
14951 editinfo_dlg[13].dp = (void *) &msgs_list;
14952
14953 large_dialog(editinfo_dlg);
14954
14955 int32_t ret = do_zqdialog(editinfo_dlg,-1);
14956
14957 if(ret==16)
14958 {
14959 mark_save_dirty();
14960 QMisc.info[index].price[0] = vbound(atoi(ps1), 0, 65535);
14961 QMisc.info[index].price[1] = vbound(atoi(ps2), 0, 65535);
14962 QMisc.info[index].price[2] = vbound(atoi(ps3), 0, 65535);
14963 strncpy(QMisc.info[index].name,infoname,32);
14964 str1 = editinfo_dlg[9].d1;
14965 str2 = editinfo_dlg[11].d1;
14966 str3 = editinfo_dlg[13].d1;
14967 QMisc.info[index].str[0] = msg_at_pos(str1);
14968 QMisc.info[index].str[1] = msg_at_pos(str2);
14969 QMisc.info[index].str[2] = msg_at_pos(str3);
14970
14971 //move 0s to the end
14972 word swaptmp;
14973
14974 if(QMisc.info[index].str[0] == 0)
14975 {
14976 //possibly permute the infos
14977 if(QMisc.info[index].str[1] != 0)
14978 {
14979 //swap
14980 swaptmp = QMisc.info[index].str[0];
14981 QMisc.info[index].str[0] = QMisc.info[index].str[1];
14982 QMisc.info[index].str[1] = swaptmp;
14983 swaptmp = QMisc.info[index].price[0];
14984 QMisc.info[index].price[0] = QMisc.info[index].price[1];
14985 QMisc.info[index].price[1] = swaptmp;
14986 }
14987 else if(QMisc.info[index].str[2] != 0)
14988 {
14989 //move info 0 to 1, 1 to 2, and 2 to 0
14990 swaptmp = QMisc.info[index].str[0];
14991 QMisc.info[index].str[0] = QMisc.info[index].str[2];
14992 QMisc.info[index].str[2] = QMisc.info[index].str[1];
14993 QMisc.info[index].str[1] = swaptmp;
14994 swaptmp = QMisc.info[index].price[0];
14995 QMisc.info[index].price[0] = QMisc.info[index].price[2];
14996 QMisc.info[index].price[2] = QMisc.info[index].price[1];
14997 QMisc.info[index].price[1] = swaptmp;
14998 }
14999 }
15000
15001 if(QMisc.info[index].str[1] == 0 && QMisc.info[index].str[2] != 0)
15002 //swap
15003 {
15004 swaptmp = QMisc.info[index].str[1];
15005 QMisc.info[index].str[1] = QMisc.info[index].str[2];
15006 QMisc.info[index].str[2] = swaptmp;
15007 swaptmp = QMisc.info[index].price[1];
15008 QMisc.info[index].price[1] = QMisc.info[index].price[2];
15009 QMisc.info[index].price[2] = swaptmp;
15010 }
15011 }
15012 }
15013
15014 int32_t onInfoTypes()
15015 {
15016 info_list_size = 256;
15017
15018 int32_t index = select_data("Info Types",0,infolist,"Edit","Done",get_zc_font(font_lfont));
15019
15020 while(index!=-1)
15021 {
15022 EditInfoType(index);
15023
15024 index = select_data("Info Types",index,infolist,"Edit","Done",get_zc_font(font_lfont));
15025 }
15026
15027 return D_O_K;
15028 }
15029
15030
15031
15032 //This dialogie is self-contained, and does not use dialogue control numbers in a separate array to generate its fields.
15033 static DIALOG editshop_dlg[] =
15034 {
15035 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
15036 12 { jwin_win_proc, 0, 10, 221, 204, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
15037 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
15038 12 { jwin_text_proc, 24, 60, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "1st", NULL, NULL },
15039 12 { jwin_text_proc, 24, 106, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "2nd", NULL, NULL },
15040 12 { jwin_text_proc, 24, 152, 48, 8, vc(7), vc(1), 0, 0, 0, 0, (void *) "3rd", NULL, NULL },
15041 12 { jwin_text_proc, 56, 60, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
15042 12 { jwin_text_proc, 56, 106, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
15043 12 { jwin_text_proc, 56, 152, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Price:", NULL, NULL },
15044 // 8
15045 12 { jwin_edit_proc, 86, 56, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15046 12 { d_nidroplist_proc, 56, 74, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15047 12 { jwin_edit_proc, 86, 102, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15048 12 { d_nidroplist_proc, 56, 120, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15049 12 { jwin_edit_proc, 86, 148, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15050 12 { d_nidroplist_proc, 56, 166, 137, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15051 12 { jwin_text_proc, 24, 42, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Name:", NULL, NULL },
15052 12 { jwin_edit_proc, 56, 38, 137, 16, vc(12), vc(1), 0, 0, 31, 0, NULL, NULL, NULL },
15053
15054 // 16
15055 12 { jwin_button_proc, 40, 188, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
15056 12 { jwin_button_proc, 121, 188, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
15057 //18
15058 12 { jwin_text_proc, 130, 60, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Info:", NULL, NULL },
15059 12 { jwin_text_proc, 130, 106, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Info:", NULL, NULL },
15060 12 { jwin_text_proc, 130, 152, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Info:", NULL, NULL },
15061 // 21
15062 12 { jwin_edit_proc, 155, 56, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15063 12 { jwin_edit_proc, 155, 102, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15064 12 { jwin_edit_proc, 155, 148, 32, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15065
15066 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
15067 };
15068
15069 void EditShopType(int32_t index)
15070 {
15071
15072 build_bii_list(true);
15073 char ps1[6],ps2[6],ps3[6];
15074 char info1[6],info2[6],info3[6];
15075 char shopname[32];
15076 char caption[40];
15077
15078 sprintf(caption,"Shop Data %d",index);
15079 editshop_dlg[0].dp = caption;
15080 editshop_dlg[0].dp2=get_zc_font(font_lfont);
15081
15082 sprintf(ps1,"%d",QMisc.shop[index].price[0]);
15083 sprintf(ps2,"%d",QMisc.shop[index].price[1]);
15084 sprintf(ps3,"%d",QMisc.shop[index].price[2]);
15085
15086 sprintf(info1,"%d",QMisc.shop[index].str[0]);
15087 sprintf(info2,"%d",QMisc.shop[index].str[1]);
15088 sprintf(info3,"%d",QMisc.shop[index].str[2]);
15089
15090 sprintf(shopname,"%s",QMisc.shop[index].name);
15091 editshop_dlg[8].dp = ps1;
15092 editshop_dlg[10].dp = ps2;
15093 editshop_dlg[12].dp = ps3;
15094 editshop_dlg[15].dp = shopname;
15095
15096 editshop_dlg[21].dp = info1;
15097 editshop_dlg[22].dp = info2;
15098 editshop_dlg[23].dp = info3;
15099
15100 ListData item_list(itemlist_num, &a4fonts[font_lfont_l]);
15101
15102 editshop_dlg[9].dp = (void *) &item_list;
15103 editshop_dlg[11].dp = (void *) &item_list;
15104 editshop_dlg[13].dp = (void *) &item_list;
15105
15106 for(int32_t i=0; i<3; ++i)
15107 {
15108 if(QMisc.shop[index].hasitem[i])
15109 {
15110 for(int32_t j=0; j<bii_cnt; j++)
15111 {
15112 if(bii[j].i == QMisc.shop[index].item[i])
15113 {
15114 editshop_dlg[9+(i<<1)].d1 = j;
15115 }
15116 }
15117 }
15118 else
15119 {
15120 editshop_dlg[9+(i<<1)].d1 = -2;
15121 }
15122 }
15123
15124 large_dialog(editshop_dlg);
15125
15126 int32_t ret = do_zqdialog(editshop_dlg,-1);
15127
15128 if(ret==16)
15129 {
15130 mark_save_dirty();
15131 QMisc.shop[index].price[0] = vbound(atoi(ps1), 0, 65535);
15132 QMisc.shop[index].price[1] = vbound(atoi(ps2), 0, 65535);
15133 QMisc.shop[index].price[2] = vbound(atoi(ps3), 0, 65535);
15134
15135 QMisc.shop[index].str[0] = vbound(atoi(info1), 0, 65535);
15136 QMisc.shop[index].str[1] = vbound(atoi(info2), 0, 65535);
15137 QMisc.shop[index].str[2] = vbound(atoi(info3), 0, 65535);
15138
15139 snprintf(QMisc.shop[index].name, 32, "%s",shopname);
15140
15141 for(int32_t i=0; i<3; ++i)
15142 {
15143 if(bii[editshop_dlg[9+(i<<1)].d1].i == -2)
15144 {
15145 QMisc.shop[index].hasitem[i] = 0;
15146 QMisc.shop[index].item[i] = 0;
15147 QMisc.shop[index].price[i] = 0;
15148 }
15149 else
15150 {
15151 QMisc.shop[index].hasitem[i] = 1;
15152 QMisc.shop[index].item[i] = bii[editshop_dlg[9+(i<<1)].d1].i;
15153 }
15154 }
15155
15156 //filter all the 0 items to the end (yeah, bubble sort; sue me)
15157 word swaptmp;
15158
15159 for(int32_t j=0; j<3-1; j++)
15160 {
15161 for(int32_t k=0; k<2-j; k++)
15162 {
15163 if(QMisc.shop[index].hasitem[k]==0)
15164 {
15165 swaptmp = QMisc.shop[index].item[k];
15166 QMisc.shop[index].item[k] = QMisc.shop[index].item[k+1];
15167 QMisc.shop[index].item[k+1] = swaptmp;
15168 swaptmp = QMisc.shop[index].price[k];
15169 QMisc.shop[index].price[k] = QMisc.shop[index].price[k+1];
15170 QMisc.shop[index].price[k+1] = swaptmp;
15171 swaptmp = QMisc.shop[index].hasitem[k];
15172 QMisc.shop[index].hasitem[k] = QMisc.shop[index].item[k+1];
15173 QMisc.shop[index].hasitem[k+1] = swaptmp;
15174 }
15175 }
15176 }
15177 }
15178 }
15179
15180 int32_t onShopTypes()
15181 {
15182 shop_list_size = 256;
15183
15184 int32_t index = select_data("Shop Types",0,shoplist,"Edit","Done",get_zc_font(font_lfont));
15185
15186 while(index!=-1)
15187 {
15188 EditShopType(index);
15189 index = select_data("Shop Types",index,shoplist,"Edit","Done",get_zc_font(font_lfont));
15190 }
15191
15192 return D_O_K;
15193 }
15194
15195 void call_bottle_dlg(int32_t index);
15196 int32_t onBottleTypes()
15197 {
15198 bottle_list_size = 64;
15199 int32_t index = 0;
15200
15201 while(index > -1)
15202 {
15203 index = select_data("Bottle Types", index, bottlelist, "Edit", "Done", get_zc_font(font_lfont));
15204 if(index > -1)
15205 call_bottle_dlg(index);
15206 }
15207
15208 return D_O_K;
15209 }
15210
15211 void call_bottleshop_dlg(int32_t index);
15212 int32_t onBottleShopTypes()
15213 {
15214 bottleshop_list_size = 256;
15215 int32_t index = 0;
15216
15217 while(index > -1)
15218 {
15219 index = select_data("Bottle Shop Types", index, bottleshoplist, "Edit", "Done", get_zc_font(font_lfont));
15220 if(index > -1)
15221 call_bottleshop_dlg(index);
15222 }
15223
15224 return D_O_K;
15225 }
15226
15227 int32_t onSaveMenus()
15228 {
15229 SaveMenuListerDialog().show();
15230 return D_O_K;
15231 }
15232
15233
15234 static char item_drop_set_str_buf[70];
15235 int32_t item_drop_set_list_size=MAXITEMDROPSETS;
15236
15237 const char *itemdropsetlist(int32_t index, int32_t *list_size)
15238 {
15239 if(index>=0)
15240 {
15241 bound(index,0,item_drop_set_list_size-1);
15242 sprintf(item_drop_set_str_buf,"%3d: %s",index,item_drop_sets[index].name);
15243 return item_drop_set_str_buf;
15244 }
15245
15246 *list_size=item_drop_set_list_size;
15247 return NULL;
15248 }
15249
15250 int32_t d_itemdropedit_proc(int32_t msg,DIALOG *d,int32_t c);
15251
15252 static int32_t edititemdropset_1_list[] =
15253 {
15254 // dialog control number
15255 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,24,25,26,27,28, -1
15256 };
15257
15258 static int32_t edititemdropset_2_list[] =
15259 {
15260 // dialog control number
15261 12, 13, 29, 30, 31, 32, 33,34,35,36,37,38,39,40,41,42,43, -1
15262 };
15263
15264 static TABPANEL edititemdropset_tabs[] =
15265 {
15266 // (text)
15267 { (char *)" Page 1 ", D_SELECTED, edititemdropset_1_list, 0, NULL },
15268 { (char *)" Page 2 ", 0, edititemdropset_2_list, 0, NULL },
15269 { NULL, 0, NULL, 0, NULL }
15270 };
15271
15272 static DIALOG edititemdropset_dlg[] =
15273 {
15274 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
15275 12 { jwin_win_proc, 0, 0, 320, 240, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
15276 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
15277
15278 // 2
15279 12 { jwin_button_proc, 89, 213, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
15280 12 { jwin_button_proc, 169, 213, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
15281
15282 // 4
15283 12 { jwin_text_proc, 9, 29, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Name:", NULL, NULL },
15284 12 { jwin_edit_proc, 39, 25, 275, 16, vc(12), vc(1), 0, 0, 32, 0, NULL, NULL, NULL },
15285 12 { jwin_text_proc, 9, 47, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Nothing Chance:", NULL, NULL },
15286 12 { d_itemdropedit_proc, 84, 43, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15287
15288 12 { jwin_tab_proc, 4, 65, 312, 143, vc(0), vc(15), 0, 0, 0, 0, (void *) edititemdropset_tabs, NULL, (void *)edititemdropset_dlg },
15289 12 { jwin_text_proc, 114, 43+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15290 // 10
15291 12 { jwin_text_proc, 10, 87, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Chance:", NULL, NULL },
15292 12 { jwin_text_proc, 56, 87, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Item:", NULL, NULL },
15293 12 { jwin_text_proc, 10, 87, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Chance:", NULL, NULL },
15294 12 { jwin_text_proc, 56, 87, 88, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Item:", NULL, NULL },
15295
15296 // 14
15297 12 { d_itemdropedit_proc, 9, 96, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15298 12 { d_idroplist_proc, 55, 96, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15299 12 { jwin_text_proc, 37, 96+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15300 12 { d_itemdropedit_proc, 9, 118, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15301 12 { d_idroplist_proc, 55, 118, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15302 12 { jwin_text_proc, 37, 118+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15303 12 { d_itemdropedit_proc, 9, 140, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15304 12 { d_idroplist_proc, 55, 140, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15305 12 { jwin_text_proc, 37, 140+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15306 12 { d_itemdropedit_proc, 9, 162, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15307 12 { d_idroplist_proc, 55, 162, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15308 12 { jwin_text_proc, 37, 162+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15309 12 { d_itemdropedit_proc, 9, 184, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15310 12 { d_idroplist_proc, 55, 184, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15311 12 { jwin_text_proc, 37, 184+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15312 // 29
15313 12 { d_itemdropedit_proc, 9, 96, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15314 12 { d_idroplist_proc, 55, 96, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15315 12 { jwin_text_proc, 37, 96+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15316 12 { d_itemdropedit_proc, 9, 118, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15317 12 { d_idroplist_proc, 55, 118, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15318 12 { jwin_text_proc, 37, 118+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15319 12 { d_itemdropedit_proc, 9, 140, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15320 12 { d_idroplist_proc, 55, 140, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15321 12 { jwin_text_proc, 37, 140+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15322 12 { d_itemdropedit_proc, 9, 162, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15323 12 { d_idroplist_proc, 55, 162, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15324 12 { jwin_text_proc, 37, 162+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15325 12 { d_itemdropedit_proc, 9, 184, 26, 16, vc(12), vc(1), 0, 0, 5, 0, NULL, NULL, NULL },
15326 12 { d_idroplist_proc, 55, 184, 233, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
15327 12 { jwin_text_proc, 39, 184+4, 26, 16, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
15328 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
15329 };
15330
15331 int32_t d_itemdropedit_proc(int32_t msg,DIALOG *d,int32_t c)
15332 {
15333 int32_t ret = jwin_edit_proc(msg,d,c);
15334
15335 if(msg==MSG_DRAW)
15336 {
15337 int32_t t = atoi((char*)edititemdropset_dlg[7].dp);
15338
15339 for(int32_t i=0; i<10; ++i)
15340 {
15341 t += atoi((char*)edititemdropset_dlg[14+(i*3)].dp);
15342 }
15343
15344 {
15345 int32_t t2 = (int32_t)(100*atoi((char*)edititemdropset_dlg[7].dp) / zc_max(t,1));
15346 sprintf((char*)edititemdropset_dlg[9].dp,"%d%%%s",t2, t2 <= 11 ? " ":"");
15347 object_message(&edititemdropset_dlg[9],MSG_DRAW,c);
15348 }
15349
15350 for(int32_t i=0; i<10; ++i)
15351 {
15352 int32_t t2 = (int32_t)(100*atoi((char*)edititemdropset_dlg[14+(i*3)].dp) / zc_max(t,1));
15353 sprintf((char*)edititemdropset_dlg[16+(i*3)].dp,"%d%%%s",t2, t2 <= 11 ? " ":"");
15354 object_message(&edititemdropset_dlg[16+(i*3)],MSG_DRAW,c);
15355 }
15356
15357 }
15358
15359 return ret;
15360 }
15361
15362 void EditItemDropSet(int32_t index)
15363 {
15364 build_bii_list(true);
15365 char chance[11][10];
15366 char itemdropsetname[64];
15367 char caption[40];
15368 char percent_str[11][5];
15369
15370 sprintf(caption,"Item Drop Set Data %d",index);
15371 edititemdropset_dlg[0].dp = caption;
15372 edititemdropset_dlg[0].dp2=get_zc_font(font_lfont);
15373
15374 sprintf(itemdropsetname,"%s",item_drop_sets[index].name);
15375 edititemdropset_dlg[5].dp = itemdropsetname;
15376
15377 sprintf(chance[0],"%d",item_drop_sets[index].chance[0]);
15378 edititemdropset_dlg[7].dp = chance[0];
15379
15380 ListData item_list(itemlist_num, &a4fonts[font_lfont_l]);
15381 sprintf(percent_str[0]," ");
15382 edititemdropset_dlg[9].dp = percent_str[0];
15383
15384 for(int32_t i=0; i<10; ++i)
15385 {
15386 sprintf(chance[i+1],"%d",item_drop_sets[index].chance[i+1]);
15387 edititemdropset_dlg[14+(i*3)].dp = chance[i+1];
15388 edititemdropset_dlg[15+(i*3)].dp = (void *) &item_list;
15389 sprintf(percent_str[i+1]," ");
15390 edititemdropset_dlg[16+(i*3)].dp = percent_str[i+1];
15391
15392 if(item_drop_sets[index].chance[i+1]==0)
15393 {
15394 edititemdropset_dlg[15+(i*3)].d1 = -2;
15395 }
15396 else
15397 {
15398 for(int32_t j=0; j<bii_cnt; j++)
15399 {
15400 if(bii[j].i == item_drop_sets[index].item[i])
15401 {
15402 edititemdropset_dlg[15+(i*3)].d1 = j;
15403 }
15404 }
15405 }
15406 }
15407
15408 large_dialog(edititemdropset_dlg);
15409
15410 int32_t ret = do_zqdialog(edititemdropset_dlg,-1);
15411
15412 if(ret==2)
15413 {
15414 mark_save_dirty();
15415
15416 sprintf(item_drop_sets[index].name,"%s",itemdropsetname);
15417
15418 item_drop_sets[index].chance[0]=atoi(chance[0]);
15419
15420 for(int32_t i=0; i<10; ++i)
15421 {
15422 item_drop_sets[index].chance[i+1]=atoi(chance[i+1]);
15423
15424 if(bii[edititemdropset_dlg[15+(i*3)].d1].i == -2)
15425 {
15426 item_drop_sets[index].chance[i+1]=0;
15427 }
15428 else
15429 {
15430 item_drop_sets[index].item[i] = bii[edititemdropset_dlg[15+(i*3)].d1].i;
15431 }
15432
15433 if(item_drop_sets[index].chance[i+1]==0)
15434 {
15435 item_drop_sets[index].item[i] = 0;
15436 }
15437 }
15438 }
15439 }
15440
15441 9 int32_t count_item_drop_sets()
15442 {
15443 9 int32_t count=0;
15444 9 bool found=false;
15445
15446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2195 times.
2195 for(count=255; (count>0); --count)
15447 {
15448
2/2
✓ Branch 0 taken 2186 times.
✓ Branch 1 taken 24056 times.
26242 for(int32_t i=0; (i<11); ++i)
15449 {
15450
2/2
✓ Branch 0 taken 24047 times.
✓ Branch 1 taken 9 times.
24056 if(item_drop_sets[count].chance[i]!=0)
15451 {
15452 9 found=true;
15453 9 break;
15454 }
15455 24047 }
15456
15457
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2186 times.
2195 if(found)
15458 {
15459 9 break;
15460 }
15461 2186 }
15462
15463 9 return count+1;
15464 }
15465
15466 int32_t onItemDropSets()
15467 {
15468 item_drop_set_list_size = MAXITEMDROPSETS;
15469
15470 int32_t index = select_data("Item Drop Sets",0,itemdropsetlist,"Edit","Done",get_zc_font(font_lfont));
15471
15472 while(index!=-1)
15473 {
15474 EditItemDropSet(index);
15475 index = select_data("Item Drop Sets",index,itemdropsetlist,"Edit","Done",get_zc_font(font_lfont));
15476 }
15477
15478 return D_O_K;
15479 }
15480
15481 int32_t curr_ring = 0;
15482
15483 void EditWarpRingScr(int32_t ring,int32_t index)
15484 {
15485 char caption[40],buf[10];
15486 restore_mouse();
15487
15488 sprintf(caption,"Ring %d Warp %d",ring,index+1);
15489 warpring_warp_dlg[0].dp = (void *)caption;
15490 warpring_warp_dlg[0].dp2=get_zc_font(font_lfont);
15491
15492 sprintf(buf,"%02X",QMisc.warp[ring].scr[index]);
15493 warpring_warp_dlg[3].d1 = QMisc.warp[ring].dmap[index];
15494 warpring_warp_dlg[4].dp = buf;
15495 warpring_warp_dlg[8].dp = buf;
15496 warpring_warp_dlg[8].dp3 = &warpring_warp_dlg[3].d1;
15497
15498 vector<DIALOG*> dlgs;
15499 dlgs.push_back(&warpring_warp_dlg[3]);
15500 dlgs.push_back(&warpring_warp_dlg[4]);
15501 warpring_warp_dlg[8].dp2 = &dlgs;
15502
15503 dmap_list_size=MAXDMAPS;
15504 dmap_list_zero=true;
15505
15506 large_dialog(warpring_warp_dlg);
15507
15508 int32_t ret=do_zqdialog(warpring_warp_dlg,-1);
15509
15510 if(ret==5 || ret==6)
15511 {
15512 mark_save_dirty();
15513 QMisc.warp[ring].dmap[index] = warpring_warp_dlg[3].d1;
15514 QMisc.warp[ring].scr[index] = zc_xtoi(buf);
15515 }
15516
15517 if(ret==6)
15518 {
15519 Map.dowarp2(ring,index);
15520 refresh(rALL);
15521 }
15522 }
15523
15524 int32_t d_warplist_proc(int32_t msg,DIALOG *d,int32_t c)
15525 {
15526 if(msg==MSG_DRAW)
15527 {
15528 int32_t *xy = (int32_t*)(d->dp3);
15529 int32_t ring = curr_ring;
15530 int32_t dmap = QMisc.warp[ring].dmap[d->d1];
15531 float temp_scale = 1.5;
15532
15533 drawdmap(dmap);
15534
15535 if(xy[0]||xy[1])
15536 {
15537 int32_t x = d->x+int32_t((xy[0]-2)*temp_scale);
15538 int32_t y = d->y+int32_t((xy[1]-2)*temp_scale);
15539 int32_t w = 84;
15540 int32_t h = 52;
15541 jwin_draw_frame(screen,x,y,w,h,FR_DEEP);
15542 drawdmap_screen(x+2,y+2,w-4,h-4,dmap);
15543 }
15544
15545 if(xy[2]||xy[3])
15546 {
15547 textprintf_ex(screen,font,d->x+int32_t(xy[2]*temp_scale),d->y+int32_t(xy[3]*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Map: %d ",DMaps[dmap].map+1);
15548 }
15549
15550 if(xy[4]||xy[5])
15551 {
15552 textprintf_ex(screen,font,d->x+int32_t(xy[4]*temp_scale),d->y+int32_t(xy[5]*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Level:%2d ",DMaps[dmap].level);
15553 }
15554
15555 if(xy[6]||xy[7])
15556 {
15557 textprintf_ex(screen,font,d->x+int32_t(xy[6]*temp_scale),d->y+int32_t(xy[7]*temp_scale),jwin_pal[jcBOXFG],jwin_pal[jcBOX],"Scr: 0x%02X ",QMisc.warp[ring].scr[d->d1]);
15558 }
15559 }
15560
15561 return jwin_list_proc(msg,d,c);
15562 }
15563
15564 int32_t d_wclist_proc(int32_t msg,DIALOG *d,int32_t c)
15565 {
15566 int32_t d1 = d->d1;
15567 int32_t ret = jwin_droplist_proc(msg,d,c);
15568 QMisc.warp[curr_ring].size=d->d1+3;
15569
15570 if(d->d1 != d1)
15571 return D_CLOSE;
15572
15573 return ret;
15574 }
15575
15576 const char *wclist(int32_t index, int32_t *list_size)
15577 {
15578 static char buf[2];
15579
15580 if(index>=0)
15581 {
15582 if(index>6)
15583 index=6;
15584
15585 sprintf(buf,"%d",index+3);
15586 return buf;
15587 }
15588
15589 *list_size=7;
15590 return NULL;
15591 }
15592
15593 //int32_t warpringdmapxy[8] = {160,116,160,90,160,102,160,154};
15594 int32_t warpringdmapxy[8] = {80,26,80,0,80,12,80,78};
15595
15596 12 static ListData number_list(numberlist, &font);
15597 12 static ListData wc_list(wclist, &font);
15598
15599 static DIALOG warpring_dlg[] =
15600 {
15601 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
15602 12 { jwin_win_proc, 0, 0, 193, 166, vc(14), vc(1), 0, D_EXIT, 0, 0, NULL, NULL, NULL },
15603 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
15604 12 { jwin_text_proc, 16, 33, 48, 8, vc(14), vc(1), 0, 0, 0, 0, (void *) "Count:", NULL, NULL },
15605 12 { d_wclist_proc, 72, 29, 48, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 1, 0, (void *) &wc_list, NULL, NULL },
15606 // 4
15607 12 { d_warplist_proc, 16, 50, 65, 71, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, (void *) &number_list, NULL, warpringdmapxy },
15608 12 { jwin_button_proc, 26, 140, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Edit", NULL, NULL },
15609 12 { jwin_button_proc, 106, 140, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Done", NULL, NULL },
15610 12 { d_keyboard_proc, 0, 0, 0, 0, 0, 0, 0, 0, KEY_F1, 0, (void *) onHelp, NULL, NULL },
15611 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
15612 };
15613
15614 int32_t select_warp()
15615 {
15616 QMisc.warp[curr_ring].size = vbound(QMisc.warp[curr_ring].size,3,9);
15617 number_list_zero = false;
15618
15619 int32_t ret=4;
15620
15621 large_dialog(warpring_dlg);
15622
15623 do
15624 {
15625 number_list_size = QMisc.warp[curr_ring].size;
15626 warpring_dlg[3].d1 = QMisc.warp[curr_ring].size-3;
15627 ret = do_zqdialog(warpring_dlg,ret);
15628 }
15629 while(ret==3);
15630
15631 if(ret==6 || ret==0)
15632 {
15633 return -1;
15634 }
15635
15636 return warpring_dlg[4].d1;
15637 }
15638
15639 void EditWarpRing(int32_t ring)
15640 {
15641 char buf[40];
15642 sprintf(buf,"Ring %d Warps",ring);
15643 warpring_dlg[0].dp = buf;
15644 warpring_dlg[0].dp2 = get_zc_font(font_lfont);
15645 curr_ring = ring;
15646
15647 int32_t index = select_warp();
15648
15649 while(index!=-1)
15650 {
15651 EditWarpRingScr(ring,index);
15652 index = select_warp();
15653 }
15654 }
15655
15656 int32_t onWarpRings()
15657 {
15658 number_list_size = 9;
15659 number_list_zero = true;
15660
15661 int32_t index = select_data("Warp Rings",0,numberlist,"Edit","Done",get_zc_font(font_lfont));
15662
15663 while(index!=-1)
15664 {
15665 EditWarpRing(index);
15666 number_list_size = 9;
15667 number_list_zero = true;
15668 index = select_data("Warp Rings",index,numberlist,"Edit","Done",get_zc_font(font_lfont));
15669 }
15670
15671 return D_O_K;
15672 }
15673
15674 enemy_struct bie[eMAXGUYS];
15675 enemy_struct ce[100];
15676 int32_t enemy_type=0,bie_cnt=-1,ce_cnt;
15677
15678 //Uses old_max_guys[] in zq_misc.cpp to define what are visible if bool hide is set true. -Z
15679 void build_bie_list(bool hide)
15680 {
15681 bie[0].s = (char *)"(None)";
15682 bie[0].i = 0;
15683 bie_cnt=1;
15684
15685 for(int32_t i=1; i<eMAXGUYS; i++)
15686 {
15687 if (i < eSTART) continue; // ignore guys - enemies only!
15688
15689 if(i >= OLDMAXGUYS || old_guy_string[i][strlen(old_guy_string[i])-1]!=' ' || !hide)
15690 {
15691 bie[bie_cnt].s = (char *)guy_string[i];
15692 bie[bie_cnt].i = i;
15693 ++bie_cnt;
15694 }
15695 }
15696
15697 for(int32_t i=1; i<bie_cnt-1; i++) //Start at 1 so '(None)' isn't alphabetized!
15698 {
15699 for(int32_t j=i+1; j<bie_cnt; j++)
15700 {
15701 if(strcmp(bie[i].s,bie[j].s)>0)
15702 {
15703 zc_swap(bie[i],bie[j]);
15704 }
15705 }
15706 }
15707 }
15708
15709 int32_t efrontfacingtile(int32_t id)
15710 {
15711 int32_t anim = get_qr(qr_NEWENEMYTILES)?guysbuf[id].e_anim:guysbuf[id].anim;
15712 int32_t usetile = 0;
15713
15714 switch(anim)
15715 {
15716
15717 case aNONE: break;
15718 case aAQUA:
15719 if(!(get_qr(qr_NEWENEMYTILES) && guysbuf[id].attributes[0]))
15720 break;
15721
15722 case aWALLM:
15723 case aGHOMA:
15724 usetile=1;
15725 break;
15726
15727 //Fallthrough
15728 case a2FRM4DIR:
15729 case aWALK:
15730 usetile=2;
15731 break;
15732
15733 case aLEV:
15734 case a3FRM4DIR:
15735 usetile=3;
15736 break;
15737
15738 case aLANM:
15739 usetile = !(get_qr(qr_NEWENEMYTILES))?0:4;
15740 break;
15741
15742 case aNEWDONGO:
15743 case a4FRM8EYE:
15744 case aNEWWIZZ:
15745 case aARMOS4:
15746 case aNEWTEK:
15747 case aNEWWALLM:
15748 case a4FRM4DIRF:
15749 case a4FRM4DIR:
15750 case a4FRM8DIRF:
15751 case a4FRMPOS8DIR:
15752 case a4FRMPOS8DIRF:
15753 case a4FRMPOS4DIR:
15754 case a4FRMPOS4DIRF:
15755 usetile=4;
15756 break;
15757
15758 case aDONGO:
15759 usetile=6;
15760 break;
15761
15762 case aDONGOBS:
15763 usetile=24;
15764 break;
15765
15766 case aNEWLEV:
15767 usetile=40;
15768 break;
15769
15770 case aNEWZORA:
15771 if(guysbuf[id].type==eeZORA)
15772 usetile=44;
15773
15774 break;
15775
15776 case aGLEEOK:
15777 if(!get_qr(qr_NEWENEMYTILES))
15778 usetile = (guysbuf[id].s_tile - guysbuf[id].tile)+1;
15779 else
15780 usetile = (guysbuf[id].attributes[7]);
15781
15782 break;
15783 }
15784
15785 return zc_max(get_qr(qr_NEWENEMYTILES) ? -guysbuf[id].e_tile
15786 : -guysbuf[id].tile, usetile);
15787 }
15788
15789 int32_t onEnemies()
15790 {
15791 call_screenenemies_dialog();
15792 refresh(rALL);
15793 return D_O_K;
15794 }
15795
15796 int32_t onHeader()
15797 {
15798 call_header_dlg();
15799 return D_O_K;
15800 }
15801
15802 void call_cheats_dlg();
15803 int32_t onCheats()
15804 {
15805 call_cheats_dlg();
15806 return D_O_K;
15807 }
15808
15809 bool do_x_button(BITMAP *dest, int32_t x, int32_t y)
15810 {
15811 bool over=false;
15812
15813 while(gui_mouse_b())
15814 {
15815 custom_vsync();
15816
15817 if(isinRect(gui_mouse_x(),gui_mouse_y(),x,y,x+15,y+13))
15818 {
15819 if(!over)
15820 {
15821 draw_x_button(dest, x, y, D_SELECTED);
15822 over=true;
15823 }
15824 }
15825 else
15826 {
15827 if(over)
15828 {
15829 draw_x_button(dest, x, y, 0);
15830 over=false;
15831 }
15832 }
15833 }
15834
15835 return over;
15836 }
15837
15838 bool do_question_button(BITMAP *dest, int32_t x, int32_t y)
15839 {
15840 bool over=false;
15841
15842 while(gui_mouse_b())
15843 {
15844 custom_vsync();
15845
15846 if(isinRect(gui_mouse_x(),gui_mouse_y(),x,y,x+15,y+13))
15847 {
15848 if(!over)
15849 {
15850 draw_question_button(dest, x, y, D_SELECTED);
15851 over=true;
15852 }
15853 }
15854 else
15855 {
15856 if(over)
15857 {
15858 draw_question_button(dest, x, y, 0);
15859 over=false;
15860 }
15861 }
15862 }
15863
15864 return over;
15865 }
15866
15867
15868 int32_t d_dummy_proc(int32_t,DIALOG *,int32_t)
15869 {
15870 return D_O_K;
15871 }
15872
15873 static int32_t last_combo=0;
15874 static int32_t last_cset=0;
15875
3/4
✓ Branch 0 taken 98304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 98292 times.
✓ Branch 3 taken 12 times.
98304 static combo_alias temp_aliases[MAXCOMBOALIASES];
15876
15877 extern int32_t scheme[jcMAX];
15878
15879 int32_t d_comboa_proc(int32_t msg,DIALOG *d,int32_t c)
15880 {
15881 //these are here to bypass compiler warnings about unused arguments
15882 c=c;
15883
15884 combo_alias *combo;
15885 combo = &temp_aliases[comboa_cnt];
15886 int32_t position;
15887 int32_t cur_layer, temp_layer;
15888 int32_t lay_count=0;
15889 int32_t size = 2;
15890
15891 int32_t cx1=(gui_mouse_x()-d->x-(120-(combo->width*8)));
15892 int32_t cy1=(gui_mouse_y()-d->y-(80-(combo->height*8)));
15893 int32_t cx=cx1/(16*size);
15894 int32_t cy=cy1/(16*size);
15895
15896 int32_t co,cs;
15897
15898
15899 switch(msg)
15900 {
15901 case MSG_CLICK:
15902 if((cx>combo->width)||(cx1<0))
15903 return D_O_K;
15904
15905 if((cy>combo->height)||(cy1<0))
15906 return D_O_K;
15907
15908 for(int32_t j=0; j<layer_cnt; j++)
15909 {
15910 if(combo->layermask&(1<<j))
15911 lay_count++;
15912 }
15913
15914 position=(lay_count)*(combo->width+1)*(combo->height+1);
15915 position+=(cy*(combo->width+1))+cx;
15916
15917 if(key[KEY_LSHIFT]||key[KEY_RSHIFT])
15918 {
15919 combo->combos[position] = 0;
15920 combo->csets[position] = 0;
15921
15922 while(gui_mouse_b())
15923 {
15924 /* do nothing */
15925 rest(1);
15926 }
15927
15928 return D_REDRAW;
15929 }
15930
15931 co=combo->combos[position];
15932 cs=combo->csets[position];
15933
15934 if((co==0)||(key[KEY_ZC_LCONTROL]))
15935 {
15936 co=last_combo;
15937 cs=last_cset;
15938 }
15939
15940 if((select_combo_2(co,cs)))
15941 {
15942 last_combo = co;
15943 last_cset = cs;
15944
15945 combo->combos[position]=co;
15946 combo->csets[position]=cs;
15947 }
15948
15949 return D_REDRAW;
15950 break;
15951
15952 case MSG_DRAW:
15953 BITMAP *buf = create_bitmap_ex(8,d->w,d->h);
15954
15955 if(buf)
15956 {
15957 clear_bitmap(buf);
15958
15959 for(int32_t z=0; z<=comboa_lmasktotal(combo->layermask); z++)
15960 {
15961 int32_t k=0;
15962 cur_layer=0;
15963 temp_layer=combo->layermask;
15964
15965 while((temp_layer!=0)&&(k<z))
15966 {
15967 if(temp_layer&1)
15968 {
15969 k++;
15970 }
15971
15972 cur_layer++;
15973 temp_layer = temp_layer>>1;
15974 }
15975
15976 for(int32_t y=0; (y<d->h)&&((y/16)<=combo->height); y+=16)
15977 {
15978 for(int32_t x=0; (x<d->w)&&((x/16)<=combo->width); x+=16)
15979 {
15980 int32_t cpos = (z*(combo->width+1)*(combo->height+1))+(((y/16)*(combo->width+1))+(x/16));
15981
15982 if(combo->combos[cpos])
15983 {
15984 if(!((d-1)->flags&D_SELECTED)||(cur_layer==layer_cnt))
15985 {
15986 if(z==0)
15987 {
15988 puttile16(buf,combobuf[combo->combos[cpos]].tile,x,y,combo->csets[cpos],combobuf[combo->combos[cpos]].flip);
15989 }
15990 else
15991 {
15992 overtile16(buf,combobuf[combo->combos[cpos]].tile,x,y,combo->csets[cpos],combobuf[combo->combos[cpos]].flip);
15993 }
15994 }
15995 }
15996 }
15997 }
15998 }
15999
16000 rectfill(screen, d->x-2,d->y-2,d->x+256+2,d->y+176+2,jwin_pal[jcBOX]);
16001 int32_t dx = 120-(combo->width*8)+d->x;
16002 int32_t dy = 80-(combo->height*8)+d->y;
16003 stretch_blit(buf,screen,0,0,(combo->width+1)*16,(combo->height+1)*16,dx,dy,(combo->width+1)*16*size,(combo->height+1)*16*size);
16004 //blit(buf,screen,0,0,120-(combo->width*8)+d->x,80-(combo->height*8)+d->y,(combo->width+1)*16,(combo->height+1)*16);
16005 (d-11)->w = (combo->width+1)*16*size+2;
16006 (d-11)->h = (combo->height+1)*16*size+2;
16007 (d-11)->x = 120-(combo->width*8)+4*size+2+(d-14)->x;
16008 (d-11)->y = 80-(combo->height*8)+25*size+2+(d-14)->y;
16009 object_message((d-11),MSG_DRAW,0);
16010
16011 destroy_bitmap(buf);
16012 }
16013
16014 break;
16015 }
16016
16017 return D_O_K;
16018 }
16019
16020 void draw_combo_alias_thumbnail(BITMAP *dest, combo_alias const* combo, int32_t x, int32_t y, int32_t size)
16021 {
16022 if(!combo->combo)
16023 {
16024 int32_t cur_layer, temp_layer;
16025
16026 int32_t cw=combo->width+1;
16027 int32_t ch=combo->height+1;
16028 int32_t dw=cw<<4;
16029 int32_t dh=ch<<4;
16030 int32_t sw=16, sh=16, sx=0, sy=0;
16031
16032 if(cw<ch)
16033 {
16034 sw=((cw<<4)/ch);
16035 sx=((16-sw)>>1);
16036 }
16037 else
16038 {
16039 sh=((ch<<4)/cw);
16040 sy=((16-sh)>>1);
16041 }
16042
16043 BITMAP *buf = create_bitmap_ex(8,dw,dh);
16044 BITMAP *buf2 = create_bitmap_ex(8, 16*size, 16*size);
16045 clear_bitmap(buf);
16046 clear_bitmap(buf2);
16047
16048 if(buf&&(combo->width>0||combo->height>0||combo->combos[0]>0))
16049 {
16050 clear_bitmap(buf);
16051
16052 for(int32_t z=0; z<=comboa_lmasktotal(combo->layermask); z++)
16053 {
16054 int32_t k=0;
16055 cur_layer=0;
16056 temp_layer=combo->layermask;
16057
16058 while((temp_layer!=0)&&(k<z))
16059 {
16060 if(temp_layer&1)
16061 {
16062 k++;
16063 }
16064
16065 cur_layer++;
16066 temp_layer = temp_layer>>1;
16067 }
16068
16069 for(int32_t y2=0; (y2<dh)&&((y2>>4)<=combo->height); y2+=16)
16070 {
16071 for(int32_t x2=0; (x2<dw)&&((x2>>4)<=combo->width); x2+=16)
16072 {
16073 int32_t cpos = (z*(combo->width+1)*(combo->height+1))+(((y2/16)*(combo->width+1))+(x2/16));
16074
16075 if(combo->combos[cpos])
16076 {
16077 if(z==0)
16078 {
16079 puttile16(buf,combobuf[combo->combos[cpos]].tile,x2,y2,combo->csets[cpos],combobuf[combo->combos[cpos]].flip);
16080 }
16081 else
16082 {
16083 overtile16(buf,combobuf[combo->combos[cpos]].tile,x2,y2,combo->csets[cpos],combobuf[combo->combos[cpos]].flip);
16084 }
16085 }
16086 }
16087 }
16088 }
16089
16090 stretch_blit(buf, buf2, 0, 0, (cw*16), (ch*16), sx*size, sy*size, sw*size, sh*size);
16091 blit(buf2, dest, 0, 0, x, y, 16*size, 16*size);
16092 }
16093 else
16094 {
16095 rectfill(dest,x,y,x+16*size-1,y+16*size-1,0);
16096 rectfill(dest,x+3*size,y+3*size,x+12*size,y+12*size,vc(4));
16097 }
16098
16099 if(buf)
16100 destroy_bitmap(buf);
16101
16102 if(buf2)
16103 destroy_bitmap(buf2);
16104 }
16105 else
16106 {
16107 if(combobuf[combo->combo].tile>0)
16108 {
16109 rectfill(dest,x,y,x+16*size-1,y+16*size-1,0);
16110 put_combo(dest, x, y, combo->combo, combo->cset, 0, 0, size);
16111 }
16112 else
16113 {
16114 rectfill(dest,x,y,x+16*size-1,y+16*size-1,0);
16115 rectfill(dest,x+3*size,y+3*size,x+12*size,y+12*size,vc(4));
16116 }
16117 }
16118 }
16119
16120 int32_t d_comboat_proc(int32_t msg,DIALOG *d,int32_t)
16121 {
16122 switch(msg)
16123 {
16124 case MSG_CLICK:
16125 {
16126 int32_t c2;
16127 int32_t cs;
16128 c2=temp_aliases[comboa_cnt].combo;
16129 cs=temp_aliases[comboa_cnt].cset;
16130
16131 if(gui_mouse_b()&2) //right mouse button
16132 {
16133 if(c2==0&&cs==0&&!(gui_mouse_b()&1))
16134 {
16135 return D_O_K;
16136 }
16137
16138 temp_aliases[comboa_cnt].combo=0;
16139 temp_aliases[comboa_cnt].cset=0;
16140 }
16141
16142 if(gui_mouse_b()&1) //left mouse button
16143 {
16144 if(select_combo_2(c2, cs))
16145 {
16146 temp_aliases[comboa_cnt].combo=c2;
16147 temp_aliases[comboa_cnt].cset=cs;
16148 }
16149
16150 return D_REDRAW;
16151 }
16152 else
16153 {
16154 return D_REDRAWME;
16155 }
16156 }
16157 break;
16158
16159 case MSG_DRAW:
16160 draw_combo_alias_thumbnail(screen, &temp_aliases[comboa_cnt], d->x-1, d->y-1,2);
16161 break;
16162
16163 default:
16164 break;
16165 }
16166
16167 return D_O_K;
16168 }
16169
16170 int32_t d_comboa_radio_proc(int32_t msg,DIALOG *d,int32_t c);
16171
16172 static DIALOG orgcomboa_dlg[] =
16173 {
16174 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
16175 { jwin_win_proc, 0, 0, 200, 161, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Organize Combo Aliases", NULL, NULL },
16176 { jwin_button_proc, 27, 130, 61, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
16177 { jwin_button_proc, 112, 130, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
16178
16179 { jwin_radio_proc, 10, 40, 33, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Copy", NULL, NULL },
16180 { jwin_text_proc, 10, 50, 33, 9, 0, 0, 0, 0, 0, 0, (void *) "", NULL, NULL },
16181 // { jwin_radio_proc, 10, 50, 33, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Move", NULL, NULL },
16182 { jwin_radio_proc, 10, 60, 33, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Swap", NULL, NULL },
16183 /* 6 */ { jwin_edit_proc, 110, 35, 32, 16, vc(12), vc(1), 0, 0, 4, 0, NULL, NULL, NULL },
16184 { jwin_edit_proc, 110, 55, 32, 16, vc(12), vc(1), 0, 0, 4, 0, NULL, NULL, NULL },
16185 { jwin_text_proc, 60, 40, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Source", NULL, NULL },
16186 { jwin_text_proc, 60, 60, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Dest", NULL, NULL},
16187 { jwin_radio_proc, 10, 80, 60, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Insert new (before source)", NULL, NULL },
16188 { jwin_radio_proc, 10, 100, 60, 9, vc(14), vc(1), 0, 0, 0, 0, (void*) "Delete source", NULL, NULL },
16189 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16190 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
16191 };
16192
16193 static DIALOG newcomboa_dlg[] =
16194 {
16195 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
16196 { jwin_win_proc, 0, 0, 200, 161, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Combo Alias Properties", NULL, NULL },
16197 { jwin_button_proc, 27, 130, 61, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
16198 { jwin_button_proc, 112, 130, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
16199 { jwin_text_proc, 24, 34, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Alias Width", NULL, NULL },
16200 { jwin_text_proc, 24, 52, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Alias Height", NULL, NULL },
16201 { jwin_text_proc, 24, 70, 100, 8, 0, 0, 0, 0, 0, 0, (void *) "Layers to Draw On:", NULL, NULL },
16202 { jwin_edit_proc, 104, 30, 28-6, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
16203 { jwin_edit_proc, 122, 48, 28-6, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
16204 { jwin_check_proc, 24, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "1", NULL, NULL },
16205 { jwin_check_proc, 50, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "2", NULL, NULL },
16206 { jwin_check_proc, 76, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "3", NULL, NULL },
16207 { jwin_check_proc, 102, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "4", NULL, NULL },
16208 { jwin_check_proc, 128, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "5", NULL, NULL },
16209 { jwin_check_proc, 154, 86, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "6", NULL, NULL },
16210
16211
16212 // { jwin_text_proc, 24, 106, 80, 8, 0, 0, 0, 0, 0, 0, (void *) "Copy to :", NULL, NULL },
16213 //15
16214 // { jwin_edit_proc, 100, 100, 28-6, 16, vc(12), vc(1), 0, 0, 2, 0, NULL, NULL, NULL },
16215 // { jwin_check_proc, 84, 106, 24, 9, vc(12), vc(1), 0, 0, 1, 0, (void *) "", NULL, NULL },
16216
16217 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16218 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
16219 };
16220
16221 bool swapComboAlias(int32_t source, int32_t dest)
16222 {
16223 if(source==dest)
16224 return false;
16225 zc_swap(temp_aliases[source],temp_aliases[dest]);
16226 return true;
16227 }
16228
16229
16230 bool copyComboAlias(int32_t source, int32_t dest)
16231 {
16232 if(source == dest)
16233 return false;
16234 temp_aliases[dest] = temp_aliases[source];
16235 return true;
16236 }
16237
16238 int32_t getcurrentcomboalias();
16239
16240 int32_t onOrgComboAliases()
16241 {
16242 char cSrc[8];
16243 char cDest[8];
16244 sprintf(cSrc,"%d", getcurrentcomboalias());
16245 strcpy(cDest,cSrc);
16246 int32_t iSrc = 0;
16247 int32_t iDest = 0;
16248
16249 //sprintf(cSrc,"0");
16250 //sprintf(cDest,"0");
16251 orgcomboa_dlg[0].dp2=get_zc_font(font_lfont);
16252 orgcomboa_dlg[6].dp= cSrc;
16253 orgcomboa_dlg[7].dp= cDest;
16254 int32_t ret = 1;
16255 large_dialog(orgcomboa_dlg);
16256 do
16257 {
16258 iSrc = atoi((char*)orgcomboa_dlg[6].dp);
16259 iDest = atoi((char*)orgcomboa_dlg[7].dp);
16260 ret = do_zqdialog(orgcomboa_dlg,-1);
16261
16262 if(ret!=1) return ret;
16263
16264 if((atoi((char*) orgcomboa_dlg[6].dp))<0 || (atoi((char*) orgcomboa_dlg[6].dp)) > MAXCOMBOALIASES-1)
16265 {
16266 displayinfo("Error",fmt::format("Invalid source (range 0-{})", MAXCOMBOALIASES-1));
16267 ret = 1;
16268 }
16269
16270 // 10,11=ins, del
16271 if(orgcomboa_dlg[10].flags & D_SELECTED) //insert
16272 {
16273 for(int32_t j=MAXCOMBOALIASES-1; j>(atoi((char*) orgcomboa_dlg[6].dp)); --j)
16274 copyComboAlias(j-1,j);
16275 ret = -1;
16276 }
16277
16278 if(orgcomboa_dlg[11].flags & D_SELECTED) //delete
16279 {
16280 for(int32_t j=(atoi((char*) orgcomboa_dlg[6].dp)); j<MAXCOMBOALIASES-1; ++j)
16281 copyComboAlias(j+1,j);
16282 ret = -1;
16283 }
16284
16285 if((atoi((char*) orgcomboa_dlg[6].dp)) == (atoi((char*) orgcomboa_dlg[7].dp)))
16286 {
16287 displayinfo("Error","Source and dest can't be the same.");
16288 ret = 1;
16289 }
16290
16291 if((atoi((char*) orgcomboa_dlg[7].dp)) < 0 || (atoi((char*) orgcomboa_dlg[7].dp)) > MAXCOMBOALIASES-1)
16292 {
16293 displayinfo("Error",fmt::format("Invalid dest (range 0-{})", MAXCOMBOALIASES-1));
16294 ret = 1;
16295 }
16296
16297 if(orgcomboa_dlg[3].flags & D_SELECTED) //copy
16298 {
16299 copyComboAlias((atoi((char*) orgcomboa_dlg[6].dp)),(atoi((char*) orgcomboa_dlg[7].dp)));
16300 ret = -1;
16301 }
16302
16303 if(orgcomboa_dlg[5].flags & D_SELECTED) //swap
16304 {
16305 swapComboAlias((atoi((char*) orgcomboa_dlg[6].dp)),(atoi((char*) orgcomboa_dlg[7].dp)));
16306 ret = -1;
16307 }
16308 }
16309 while(ret==1);
16310 return ret;
16311 }
16312
16313 int32_t onNewComboAlias()
16314 {
16315 combo_alias *combo;
16316 combo = &temp_aliases[comboa_cnt];
16317
16318 char cwidth[5];
16319 char cheight[5];
16320 // char cp[3];
16321
16322 word temp_combos[16*11*7];
16323 byte temp_csets[16*11*7];
16324 sprintf(cwidth, "%d", combo->width+1);
16325 sprintf(cheight, "%d", combo->height+1);
16326 int32_t old_count = (comboa_lmasktotal(combo->layermask)+1)*(combo->width+1)*(combo->height+1);
16327 int32_t old_width=combo->width;
16328 int32_t old_height=combo->height;
16329 int32_t oldlayer=combo->layermask;
16330
16331 for(int32_t i=0; i<old_count; i++)
16332 {
16333 temp_csets[i] = combo->csets[i];
16334 temp_combos[i] = combo->combos[i];
16335 }
16336
16337 newcomboa_dlg[0].dp2 = get_zc_font(font_lfont);
16338 newcomboa_dlg[6].dp = cwidth;
16339 newcomboa_dlg[7].dp = cheight;
16340 newcomboa_dlg[8].flags = (combo->layermask&1)? D_SELECTED : 0;
16341 newcomboa_dlg[9].flags = (combo->layermask&2)? D_SELECTED : 0;
16342 newcomboa_dlg[10].flags = (combo->layermask&4)? D_SELECTED : 0;
16343 newcomboa_dlg[11].flags = (combo->layermask&8)? D_SELECTED : 0;
16344 newcomboa_dlg[12].flags = (combo->layermask&16)? D_SELECTED : 0;
16345 newcomboa_dlg[13].flags = (combo->layermask&32)? D_SELECTED : 0;
16346
16347 large_dialog(newcomboa_dlg);
16348
16349 int32_t ret = do_zqdialog(newcomboa_dlg,-1);
16350
16351 if(ret==1)
16352 {
16353 combo->width = ((atoi(cwidth)-1)<16)?zc_max(0,(atoi(cwidth)-1)):15;
16354 combo->height = ((atoi(cheight)-1)<11)?zc_max(0,(atoi(cheight)-1)):10;
16355 combo->layermask=0;
16356 combo->layermask |= (newcomboa_dlg[8].flags&D_SELECTED)?1:0;
16357 combo->layermask |= (newcomboa_dlg[9].flags&D_SELECTED)?2:0;
16358 combo->layermask |= (newcomboa_dlg[10].flags&D_SELECTED)?4:0;
16359 combo->layermask |= (newcomboa_dlg[11].flags&D_SELECTED)?8:0;
16360 combo->layermask |= (newcomboa_dlg[12].flags&D_SELECTED)?16:0;
16361 combo->layermask |= (newcomboa_dlg[13].flags&D_SELECTED)?32:0;
16362
16363 int32_t new_count = (comboa_lmasktotal(combo->layermask)+1)*(combo->width+1)*(combo->height+1);
16364
16365 combo->combos.clear();
16366 combo->csets.clear();
16367
16368 int32_t j=1;
16369 int32_t old_size=(old_width+1)*(old_height+1);
16370 int32_t new_start[7] =
16371 {
16372 0,
16373 ((combo->width+1)*(combo->height+1)*(1)),
16374 ((combo->width+1)*(combo->height+1)*(2)),
16375 ((combo->width+1)*(combo->height+1)*(3)),
16376 ((combo->width+1)*(combo->height+1)*(4)),
16377 ((combo->width+1)*(combo->height+1)*(5)),
16378 ((combo->width+1)*(combo->height+1)*(6))
16379 };
16380 int32_t new_layers[6] = {0,0,0,0,0,0};
16381 int32_t temp_layer = combo->layermask;
16382 int32_t temp_old = oldlayer;
16383 int32_t old_layers[6] = {0,0,0,0,0,0};
16384 int32_t k=1;
16385
16386 for(int32_t i=0; (i<6)&&(temp_layer!=0); j++,temp_layer>>=1,temp_old>>=1)
16387 {
16388 if(temp_layer&1)
16389 {
16390 new_layers[i] = j;
16391 //if(oldlayer&(1<<(j-1))) old_layers[i] = k++;
16392 i++;
16393 }
16394
16395 if(temp_old&1)
16396 {
16397 if(temp_layer&1)
16398 {
16399 old_layers[i-1] = k;
16400 }
16401
16402 k++;
16403 }
16404 }
16405
16406 for(int32_t i=0; i<new_count; i++)
16407 {
16408 if(i>=new_start[6])
16409 {
16410 //oldl=oldlayer>>(new_layers[5]-1);
16411 j=i-new_start[6];
16412
16413 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[5]-1))))
16414 {
16415 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[5])];
16416 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[5])];
16417 }
16418 else
16419 {
16420 combo->combos[i] = 0;
16421 combo->csets[i] = 0;
16422 }
16423 }
16424 else if(i>=new_start[5])
16425 {
16426 //oldl=oldlayer>>(new_layers[4]-1);
16427 j=i-new_start[5];
16428
16429 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[4]-1))))
16430 {
16431 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[4])];
16432 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[4])];
16433 }
16434 else
16435 {
16436 combo->combos[i] = 0;
16437 combo->csets[i] = 0;
16438 }
16439 }
16440 else if(i>=new_start[4])
16441 {
16442 //oldl=oldlayer>>(new_layers[3]-1);
16443 j=i-new_start[4];
16444
16445 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[3]-1))))
16446 {
16447 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[3])];
16448 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[3])];
16449 }
16450 else
16451 {
16452 combo->combos[i] = 0;
16453 combo->csets[i] = 0;
16454 }
16455 }
16456 else if(i>=new_start[3])
16457 {
16458 //oldl=oldlayer>>(new_layers[2]-1);
16459 j=i-new_start[3];
16460
16461 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[2]-1))))
16462 {
16463 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[2])];
16464 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[2])];
16465 }
16466 else
16467 {
16468 combo->combos[i] = 0;
16469 combo->csets[i] = 0;
16470 }
16471 }
16472 else if(i>=new_start[2])
16473 {
16474 //oldl=oldlayer>>(new_layers[1]-1);
16475 j=i-new_start[2];
16476
16477 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[1]-1))))
16478 {
16479 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[1])];
16480 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[1])];
16481 }
16482 else
16483 {
16484 combo->combos[i] = 0;
16485 combo->csets[i] = 0;
16486 }
16487 }
16488 else if(i>=new_start[1])
16489 {
16490 //oldl=oldlayer>>(new_layers[0]-1);
16491 j=i-new_start[1];
16492
16493 if(((j/(combo->width+1))<=old_height)&&((j%(combo->width+1))<=old_width)&&(oldlayer&(1<<(new_layers[0]-1))))
16494 {
16495 combo->combos[i] = temp_combos[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[0])];
16496 combo->csets[i] = temp_csets[((j%(combo->width+1))+((old_width+1)*(j/(combo->width+1))))+(old_size*old_layers[0])];
16497 }
16498 else
16499 {
16500 combo->combos[i] = 0;
16501 combo->csets[i] = 0;
16502 }
16503 }
16504 else if(i>=new_start[0])
16505 {
16506 if(((i/(combo->width+1))<=old_height)&&((i%(combo->width+1))<=old_width))
16507 {
16508 combo->combos[i] = temp_combos[(i%(combo->width+1))+((old_width+1)*(i/(combo->width+1)))];
16509 combo->csets[i] = temp_csets[(i%(combo->width+1))+((old_width+1)*(i/(combo->width+1)))];
16510 }
16511 else
16512 {
16513 combo->combos[i] = 0;
16514 combo->csets[i] = 0;
16515 }
16516 }
16517 }
16518
16519 set_comboaradio(combo->layermask);
16520 }
16521
16522 return ret;
16523 }
16524
16525 int32_t d_orgcomboa_proc(int32_t msg, DIALOG *d, int32_t c)
16526 {
16527 //these are here to bypass compiler warnings about unused arguments
16528 c=c;
16529
16530 int32_t down=0;
16531 int32_t selected=(d->flags&D_SELECTED)?1:0;
16532 int32_t last_draw;
16533
16534 switch(msg)
16535 {
16536
16537 case MSG_DRAW:
16538 {
16539 FONT *tfont=font;
16540 font=get_zc_font(font_lfont_l);
16541 jwin_draw_text_button(screen, d->x, d->y, d->w, d->h, (char*)d->dp, d->flags, true);
16542 font=tfont;
16543 }
16544 break;
16545
16546 case MSG_WANTFOCUS:
16547 return D_WANTFOCUS;
16548
16549 case MSG_KEY:
16550 /* close dialog? */
16551 onOrgComboAliases();
16552 return D_REDRAW;
16553
16554 /* or just toggle */
16555 /*d->flags ^= D_SELECTED;
16556 object_message(d, MSG_DRAW, 0);
16557 break;*/
16558
16559 case MSG_CLICK:
16560 last_draw = 0;
16561
16562 /* track the mouse until it is released */
16563 while(gui_mouse_b())
16564 {
16565 down = mouse_in_rect(d->x, d->y, d->w, d->h);
16566
16567 /* redraw? */
16568 if(last_draw != down)
16569 {
16570 if(down != selected)
16571 d->flags |= D_SELECTED;
16572 else
16573 d->flags &= ~D_SELECTED;
16574
16575 object_message(d, MSG_DRAW, 0);
16576 last_draw = down;
16577 }
16578
16579 /* let other objects continue to animate */
16580 broadcast_dialog_message(MSG_IDLE, 0);
16581 }
16582
16583 /* redraw in normal state */
16584 if(down)
16585 {
16586 if(d->flags&D_EXIT)
16587 {
16588 d->flags &= ~D_SELECTED;
16589 object_message(d, MSG_DRAW, 0);
16590 }
16591 }
16592
16593 /* should we close the dialog? */
16594 if(down)
16595 {
16596 onOrgComboAliases();
16597 return D_REDRAW;
16598 }
16599
16600 break;
16601 }
16602
16603 return D_O_K;
16604 }
16605
16606 int32_t d_comboabutton_proc(int32_t msg, DIALOG *d, int32_t c)
16607 {
16608 //these are here to bypass compiler warnings about unused arguments
16609 c=c;
16610
16611 int32_t down=0;
16612 int32_t selected=(d->flags&D_SELECTED)?1:0;
16613 int32_t last_draw;
16614
16615 switch(msg)
16616 {
16617
16618 case MSG_DRAW:
16619 {
16620 FONT *tfont=font;
16621 font=get_zc_font(font_lfont_l);
16622 jwin_draw_text_button(screen, d->x, d->y, d->w, d->h, (char*)d->dp, d->flags, true);
16623 font=tfont;
16624 }
16625 break;
16626
16627 case MSG_WANTFOCUS:
16628 return D_WANTFOCUS;
16629
16630 case MSG_KEY:
16631 /* close dialog? */
16632 onNewComboAlias();
16633 return D_REDRAW;
16634
16635 /* or just toggle */
16636 /*d->flags ^= D_SELECTED;
16637 object_message(d, MSG_DRAW, 0);
16638 break;*/
16639
16640 case MSG_CLICK:
16641 last_draw = 0;
16642
16643 /* track the mouse until it is released */
16644 while(gui_mouse_b())
16645 {
16646 down = mouse_in_rect(d->x, d->y, d->w, d->h);
16647
16648 /* redraw? */
16649 if(last_draw != down)
16650 {
16651 if(down != selected)
16652 d->flags |= D_SELECTED;
16653 else
16654 d->flags &= ~D_SELECTED;
16655
16656 object_message(d, MSG_DRAW, 0);
16657 last_draw = down;
16658 }
16659
16660 /* let other objects continue to animate */
16661 broadcast_dialog_message(MSG_IDLE, 0);
16662 }
16663
16664 /* redraw in normal state */
16665 if(down)
16666 {
16667 if(d->flags&D_EXIT)
16668 {
16669 d->flags &= ~D_SELECTED;
16670 object_message(d, MSG_DRAW, 0);
16671 }
16672 }
16673
16674 /* should we close the dialog? */
16675 if(down)
16676 {
16677 onNewComboAlias();
16678 return D_REDRAW;
16679 }
16680
16681 break;
16682 }
16683
16684 return D_O_K;
16685 }
16686
16687 int32_t d_comboacheck_proc(int32_t msg, DIALOG *d, int32_t c)
16688 {
16689 int32_t temp = d->flags&D_SELECTED;
16690 int32_t ret=jwin_checkfont_proc(msg,d,c);
16691
16692 if(temp != (d->flags&D_SELECTED))
16693 {
16694 return D_REDRAW;
16695 }
16696
16697 return ret;
16698 }
16699
16700 static DIALOG editcomboa_dlg[] =
16701 {
16702 /* (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp) */
16703 { jwin_win_proc, 0, 0, 320, 240, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Combo Alias Edit", NULL, NULL },
16704 { jwin_button_proc, 148, 212, 61, 21, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "O&K", NULL, NULL },
16705 { jwin_button_proc, 232, 212, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
16706 { jwin_frame_proc, 4+121, 28+81, 1, 1, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
16707 { d_comboabutton_proc, 25, 212, 81, 21, vc(14), vc(1), 'p', D_EXIT, 0, 0, (void *) "&Properties", NULL, NULL },
16708 { d_dummy_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16709 { d_comboa_radio_proc, 285, 44, 30, 8+1, vc(14), vc(1), 0, D_SELECTED, 0, 0, (void *) "0", NULL, NULL },
16710 { d_comboa_radio_proc, 285, 54, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "1", NULL, NULL },
16711 { d_comboa_radio_proc, 285, 64, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "2", NULL, NULL },
16712 { d_comboa_radio_proc, 285, 74, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "3", NULL, NULL },
16713 { d_comboa_radio_proc, 285, 84, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "4", NULL, NULL },
16714
16715 { d_comboa_radio_proc, 285, 94, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "5", NULL, NULL },
16716 { d_comboa_radio_proc, 285, 104, 30, 8+1, vc(14), vc(1), 0, 0, 0, 0, (void *) "6", NULL, NULL },
16717 { d_comboacheck_proc, 285, 164, 17, 9, vc(12), vc(1), 0, 0, 1, 0, NULL, NULL, NULL },
16718 { d_comboa_proc, 6, 27, 256, 176, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16719 { jwin_ctext_proc, 290, 176, 27, 8, 0, 0, 0, 0, 0, 0, (void *) "Only Show", NULL, NULL },
16720 { jwin_ctext_proc, 290, 186, 27, 8, 0, 0, 0, 0, 0, 0, (void *) "Current", NULL, NULL },
16721 { jwin_ctext_proc, 290, 196, 27, 8, 0, 0, 0, 0, 0, 0, (void *) "Layer", NULL, NULL },
16722 { jwin_ctext_proc, 290, 122, 27, 8, 0, 0, 0, 0, 0, 0, (void *) "Thumbnail", NULL, NULL },
16723 { jwin_frame_proc, 280, 132, 20, 20, 0, 0, 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
16724 { d_comboat_proc, 282, 134, 16, 16, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16725
16726 //21
16727 { d_orgcomboa_proc, 106, 212, 21, 21, vc(14), vc(1), 'p', D_EXIT, 0, 0, (void *) "&Org", NULL, NULL },
16728 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
16729 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
16730 };
16731
16732 int32_t getcurrentcomboalias()
16733 {
16734 return editcomboa_dlg[5].d1;
16735 }
16736
16737 int32_t d_comboa_radio_proc(int32_t msg,DIALOG *d,int32_t c)
16738 {
16739 int32_t temp = layer_cnt;
16740 int32_t ret = jwin_radiofont_proc(msg,d,c);
16741
16742 if(editcomboa_dlg[6].flags&D_SELECTED) layer_cnt=0;
16743 else if(editcomboa_dlg[7].flags&D_SELECTED) layer_cnt=1;
16744 else if(editcomboa_dlg[8].flags&D_SELECTED) layer_cnt=2;
16745 else if(editcomboa_dlg[9].flags&D_SELECTED) layer_cnt=3;
16746 else if(editcomboa_dlg[10].flags&D_SELECTED) layer_cnt=4;
16747 else if(editcomboa_dlg[11].flags&D_SELECTED) layer_cnt=5;
16748 else if(editcomboa_dlg[12].flags&D_SELECTED) layer_cnt=6;
16749
16750 if(temp != layer_cnt)
16751 {
16752 return D_REDRAW;
16753 }
16754
16755 return ret;
16756 }
16757
16758 int32_t set_comboaradio(byte layermask)
16759 {
16760 if(editcomboa_dlg[7].flags&D_SELECTED) editcomboa_dlg[7].flags &= ~D_SELECTED;
16761
16762 if(editcomboa_dlg[8].flags&D_SELECTED) editcomboa_dlg[8].flags &= ~D_SELECTED;
16763
16764 if(editcomboa_dlg[9].flags&D_SELECTED) editcomboa_dlg[9].flags &= ~D_SELECTED;
16765
16766 if(editcomboa_dlg[10].flags&D_SELECTED) editcomboa_dlg[10].flags &= ~D_SELECTED;
16767
16768 if(editcomboa_dlg[11].flags&D_SELECTED) editcomboa_dlg[11].flags &= ~D_SELECTED;
16769
16770 if(editcomboa_dlg[12].flags&D_SELECTED) editcomboa_dlg[12].flags &= ~D_SELECTED;
16771
16772 if(!(layermask&1)) editcomboa_dlg[7].flags |= D_DISABLED;
16773 else editcomboa_dlg[7].flags &= ~D_DISABLED;
16774
16775 if(!(layermask&2)) editcomboa_dlg[8].flags |= D_DISABLED;
16776 else editcomboa_dlg[8].flags &= ~D_DISABLED;
16777
16778 if(!(layermask&4)) editcomboa_dlg[9].flags |= D_DISABLED;
16779 else editcomboa_dlg[9].flags &= ~D_DISABLED;
16780
16781 if(!(layermask&8)) editcomboa_dlg[10].flags |= D_DISABLED;
16782 else editcomboa_dlg[10].flags &= ~D_DISABLED;
16783
16784 if(!(layermask&16)) editcomboa_dlg[11].flags |= D_DISABLED;
16785 else editcomboa_dlg[11].flags &= ~D_DISABLED;
16786
16787 if(!(layermask&32)) editcomboa_dlg[12].flags |= D_DISABLED;
16788 else editcomboa_dlg[12].flags &= ~D_DISABLED;
16789
16790 editcomboa_dlg[6].flags |= D_SELECTED;
16791 layer_cnt=0;
16792 return 1;
16793 }
16794
16795 int32_t onEditComboPool()
16796 {
16797 call_cpool_dlg(combo_pool_pos);
16798 return D_O_K;
16799 }
16800 int32_t onEditAutoCombo()
16801 {
16802 call_autocombo_dlg(combo_auto_pos);
16803 return D_O_K;
16804 }
16805 int32_t onEditComboAlias()
16806 {
16807 comboa_cnt = combo_apos;
16808 reset_combo_animations();
16809 reset_combo_animations2();
16810
16811 for(int32_t i=0; i<MAXCOMBOALIASES; i++)
16812 temp_aliases[i] = combo_aliases[i];
16813
16814 editcomboa_dlg[0].dp2 = get_zc_font(font_lfont);
16815 set_comboaradio(temp_aliases[comboa_cnt].layermask);
16816 editcomboa_dlg[5].d1 = comboa_cnt;
16817
16818 bool small_d1 = editcomboa_dlg[0].d1==0;
16819 large_dialog(editcomboa_dlg,2);
16820
16821 if(small_d1)
16822 {
16823 for(int32_t i=6; i<=12; i++)
16824 {
16825 editcomboa_dlg[i].w=30*1.5;
16826 editcomboa_dlg[i].h=9*1.5;
16827 }
16828
16829 editcomboa_dlg[13].w=17*1.5;
16830 editcomboa_dlg[13].h=9*1.5;
16831 editcomboa_dlg[4].w=81*1.5;
16832 editcomboa_dlg[4].h=21*1.5;
16833 editcomboa_dlg[4].dp2=get_zc_font(font_lfont_l);
16834 editcomboa_dlg[21].w=21*1.5;
16835 editcomboa_dlg[21].h=21*1.5;
16836 editcomboa_dlg[21].dp2=get_zc_font(font_lfont_l);
16837 }
16838
16839 int32_t ret=do_zqdialog(editcomboa_dlg,-1);
16840
16841 if(ret==1)
16842 {
16843 mark_save_dirty();
16844
16845 for(int32_t i=0; i<MAXCOMBOALIASES; i++)
16846 combo_aliases[i] = temp_aliases[i];
16847 }
16848
16849 setup_combo_animations();
16850 setup_combo_animations2();
16851 return D_O_K;
16852 }
16853 void call_calias_dlg(int index)
16854 {
16855 combo_apos = comboa_cnt = index;
16856 onEditComboAlias();
16857 }
16858
16859 int32_t onSelectFFCombo()
16860 {
16861 FFCListerDialog().show();
16862 return D_O_K;
16863 }
16864
16865 static int32_t as_ffc_list[] = { 4, 5, 6, -1};
16866 static int32_t as_global_list[] = { 7, 8, 9, -1}; //Why does putting 15 in here not place my message only on the global tab? ~Joe
16867 static int32_t as_item_list[] = { 10, 11, 12, -1};
16868 static int32_t as_npc_list[] = { 18, 19, 20, -1}; //npc scripts TAB
16869 static int32_t as_lweapon_list[] = { 21, 22, 23, -1}; //lweapon scripts TAB
16870 static int32_t as_eweapon_list[] = { 24, 25, 26, -1}; //eweapon scripts TAB
16871 static int32_t as_hero_list[] = { 27, 28, 29, -1}; //hero scripts TAB
16872 static int32_t as_screen_list[] = { 30, 31, 32, -1}; //screendata scripts TAB
16873 static int32_t as_dmap_list[] = { 33, 34, 35, -1}; //dmapdata scripts TAB
16874 static int32_t as_itemsprite_list[] = { 36, 37, 38, -1}; //dmapdata scripts TAB
16875 static int32_t as_comboscript_list[] = { 39, 40, 41, -1}; //combodata scripts TAB
16876 static int32_t as_genericscript_list[] = { 45, 46, 47, -1}; //generic scripts TAB
16877 static int32_t as_subscreenscript_list[] = { 48, 49, 50, -1}; //generic scripts TAB
16878
16879 static TABPANEL assignscript_tabs[] =
16880 {
16881 // (text)
16882 { (char *)"FFC", D_SELECTED, as_ffc_list, 0, NULL },
16883 { (char *)"Global", 0, as_global_list, 0, NULL },
16884 { (char *)"Item", 0, as_item_list, 0, NULL },
16885 { (char *)"NPC", 0, as_npc_list, 0, NULL },
16886 { (char *)"LWeapon", 0, as_lweapon_list, 0, NULL },
16887 { (char *)"EWeapon", 0, as_eweapon_list, 0, NULL },
16888 { (char *)"Hero", 0, as_hero_list, 0, NULL },
16889 { (char *)"DMap", 0, as_dmap_list, 0, NULL },
16890 { (char *)"Screen", 0, as_screen_list, 0, NULL },
16891 { (char *)"Item Sprite", 0, as_itemsprite_list, 0, NULL },
16892 { (char *)"Combo", 0, as_comboscript_list, 0, NULL },
16893 { (char *)"Generic", 0, as_genericscript_list, 0, NULL },
16894 { (char *)"Subscreen", 0, as_subscreenscript_list, 0, NULL },
16895 { NULL, 0, NULL, 0, NULL }
16896 };
16897
16898 const char *assignffclist(int32_t index, int32_t *list_size)
16899 {
16900 if(index<0)
16901 {
16902 *list_size = (int32_t)ffcmap.size();
16903 return NULL;
16904 }
16905
16906 return ffcmap[index].output.c_str();
16907 }
16908
16909 const char *assigngloballist(int32_t index, int32_t *list_size)
16910 {
16911 if(index<0)
16912 {
16913 *list_size = (int32_t)globalmap.size();
16914 return NULL;
16915 }
16916
16917 return globalmap[index].output.c_str();
16918 }
16919
16920 const char *assigncombolist(int32_t index, int32_t *list_size)
16921 {
16922 if(index<0)
16923 {
16924 *list_size = (int32_t)comboscriptmap.size();
16925 return NULL;
16926 }
16927
16928 return comboscriptmap[index].output.c_str();
16929 }
16930
16931 const char *assigngenericlist(int32_t index, int32_t *list_size)
16932 {
16933 if(index<0)
16934 {
16935 *list_size = ((int32_t)genericmap.size());
16936 return NULL;
16937 }
16938
16939 return genericmap[index].output.c_str();
16940 }
16941
16942 const char *assignsubscreenlist(int32_t index, int32_t *list_size)
16943 {
16944 if(index<0)
16945 {
16946 *list_size = ((int32_t)subscreenmap.size());
16947 return NULL;
16948 }
16949
16950 return subscreenmap[index].output.c_str();
16951 }
16952
16953 const char *assignitemlist(int32_t index, int32_t *list_size)
16954 {
16955 if(index<0)
16956 {
16957 *list_size = (int32_t)itemmap.size();
16958 return NULL;
16959 }
16960
16961 return itemmap[index].output.c_str();
16962 }
16963 const char *assignnpclist(int32_t index, int32_t *list_size)
16964 {
16965 if(index<0)
16966 {
16967 *list_size = (int32_t)npcmap.size();
16968 return NULL;
16969 }
16970
16971 return npcmap[index].output.c_str();
16972 }
16973
16974 const char *assignlweaponlist(int32_t index, int32_t *list_size)
16975 {
16976 if(index<0)
16977 {
16978 *list_size = (int32_t)lwpnmap.size();
16979 return NULL;
16980 }
16981
16982 return lwpnmap[index].output.c_str();
16983 }
16984
16985 const char *assigneweaponlist(int32_t index, int32_t *list_size)
16986 {
16987 if(index<0)
16988 {
16989 *list_size = (int32_t)ewpnmap.size();
16990 return NULL;
16991 }
16992
16993 return ewpnmap[index].output.c_str();
16994 }
16995
16996 const char *assignplayerlist(int32_t index, int32_t *list_size)
16997 {
16998 if(index<0)
16999 {
17000 *list_size = (int32_t)playermap.size();
17001 return NULL;
17002 }
17003
17004 return playermap[index].output.c_str();
17005 }
17006
17007 const char *assigndmaplist(int32_t index, int32_t *list_size)
17008 {
17009 if(index<0)
17010 {
17011 *list_size = (int32_t)dmapmap.size();
17012 return NULL;
17013 }
17014
17015 return dmapmap[index].output.c_str();
17016 }
17017
17018 const char *assignscreenlist(int32_t index, int32_t *list_size)
17019 {
17020 if(index<0)
17021 {
17022 *list_size = (int32_t)screenmap.size();
17023 return NULL;
17024 }
17025
17026 return screenmap[index].output.c_str();
17027 }
17028
17029 const char *assignitemspritelist(int32_t index, int32_t *list_size)
17030 {
17031 if(index<0)
17032 {
17033 *list_size = (int32_t)itemspritemap.size();
17034 return NULL;
17035 }
17036
17037 return itemspritemap[index].output.c_str();
17038 }
17039
17040 const char *assignffcscriptlist(int32_t index, int32_t *list_size)
17041 {
17042 if(index<0)
17043 {
17044 *list_size = (int32_t)asffcscripts.size();
17045 return NULL;
17046 }
17047
17048 return asffcscripts[index].c_str();
17049 }
17050
17051 const char *assignglobalscriptlist(int32_t index, int32_t *list_size)
17052 {
17053 if(index<0)
17054 {
17055 *list_size = (int32_t)asglobalscripts.size();
17056 return NULL;
17057 }
17058
17059 return asglobalscripts[index].c_str();
17060 }
17061
17062 const char *assignitemscriptlist(int32_t index, int32_t *list_size)
17063 {
17064 if(index<0)
17065 {
17066 *list_size = (int32_t)asitemscripts.size();
17067 return NULL;
17068 }
17069
17070 return asitemscripts[index].c_str();
17071 }
17072
17073 const char *assignnpcscriptlist(int32_t index, int32_t *list_size)
17074 {
17075 if(index<0)
17076 {
17077 *list_size = (int32_t)asnpcscripts.size();
17078 return NULL;
17079 }
17080
17081 return asnpcscripts[index].c_str();
17082 }
17083
17084 const char *assignlweaponscriptlist(int32_t index, int32_t *list_size)
17085 {
17086 if(index<0)
17087 {
17088 *list_size = (int32_t)aslweaponscripts.size();
17089 return NULL;
17090 }
17091
17092 return aslweaponscripts[index].c_str();
17093 }
17094
17095 const char *assigneweaponscriptlist(int32_t index, int32_t *list_size)
17096 {
17097 if(index<0)
17098 {
17099 *list_size = (int32_t)aseweaponscripts.size();
17100 return NULL;
17101 }
17102
17103 return aseweaponscripts[index].c_str();
17104 }
17105
17106 const char *assignplayerscriptlist(int32_t index, int32_t *list_size)
17107 {
17108 if(index<0)
17109 {
17110 *list_size = (int32_t)asplayerscripts.size();
17111 return NULL;
17112 }
17113
17114 return asplayerscripts[index].c_str();
17115 }
17116
17117 const char *assigndmapscriptlist(int32_t index, int32_t *list_size)
17118 {
17119 if(index<0)
17120 {
17121 *list_size = (int32_t)asdmapscripts.size();
17122 return NULL;
17123 }
17124
17125 return asdmapscripts[index].c_str();
17126 }
17127
17128 const char *assignscreenscriptlist(int32_t index, int32_t *list_size)
17129 {
17130 if(index<0)
17131 {
17132 *list_size = (int32_t)asscreenscripts.size();
17133 return NULL;
17134 }
17135
17136 return asscreenscripts[index].c_str();
17137 }
17138
17139 const char *assignitemspritescriptlist(int32_t index, int32_t *list_size)
17140 {
17141 if(index<0)
17142 {
17143 *list_size = (int32_t)asitemspritescripts.size();
17144 return NULL;
17145 }
17146
17147 return asitemspritescripts[index].c_str();
17148 }
17149
17150 const char *assigncomboscriptlist(int32_t index, int32_t *list_size)
17151 {
17152 if(index<0)
17153 {
17154 *list_size = (int32_t)ascomboscripts.size();
17155 return NULL;
17156 }
17157
17158 return ascomboscripts[index].c_str();
17159 }
17160
17161 const char *assigngenericscriptlist(int32_t index, int32_t *list_size)
17162 {
17163 if(index<0)
17164 {
17165 *list_size = (int32_t)asgenericscripts.size();
17166 return NULL;
17167 }
17168
17169 return asgenericscripts[index].c_str();
17170 }
17171
17172 const char *assignsubscreenscriptlist(int32_t index, int32_t *list_size)
17173 {
17174 if(index<0)
17175 {
17176 *list_size = (int32_t)assubscreenscripts.size();
17177 return NULL;
17178 }
17179
17180 return assubscreenscripts[index].c_str();
17181 }
17182
17183 12 static ListData assignffc_list(assignffclist, &font);
17184 12 static ListData assignffcscript_list(assignffcscriptlist, &font);
17185 12 static ListData assignglobal_list(assigngloballist, &font);
17186 12 static ListData assignglobalscript_list(assignglobalscriptlist, &font);
17187 12 static ListData assignitem_list(assignitemlist, &font);
17188 12 static ListData assignitemscript_list(assignitemscriptlist, &font);
17189 12 static ListData assignnpc_list(assignnpclist, &font);
17190 12 static ListData assignnpcscript_list(assignnpcscriptlist, &font);
17191 12 static ListData assignlweapon_list(assignlweaponlist, &font);
17192 12 static ListData assignlweaponscript_list(assignlweaponscriptlist, &font);
17193 12 static ListData assigneweapon_list(assigneweaponlist, &font);
17194 12 static ListData assigneweaponscript_list(assigneweaponscriptlist, &font);
17195
17196 12 static ListData assignplayer_list(assignplayerlist, &font);
17197 12 static ListData assignplayerscript_list(assignplayerscriptlist, &font);
17198
17199 12 static ListData assigndmap_list(assigndmaplist, &font);
17200 12 static ListData assigndmapscript_list(assigndmapscriptlist, &font);
17201
17202 12 static ListData assignscreen_list(assignscreenlist, &font);
17203 12 static ListData assignscreenscript_list(assignscreenscriptlist, &font);
17204
17205 12 static ListData assignitemsprite_list(assignitemspritelist, &font);
17206 12 static ListData assignitemspritescript_list(assignitemspritescriptlist, &font);
17207
17208 12 static ListData assigncombo_list(assigncombolist, &font);
17209 12 static ListData assigncomboscript_list(assigncomboscriptlist, &font);
17210
17211 12 static ListData assigngeneric_list(assigngenericlist, &font);
17212 12 static ListData assigngenericscript_list(assigngenericscriptlist, &font);
17213
17214 12 static ListData assignsubscreen_list(assignsubscreenlist, &font);
17215 12 static ListData assignsubscreenscript_list(assignsubscreenscriptlist, &font);
17216
17217 static DIALOG assignscript_dlg[] =
17218 {
17219 // x y w h fg bg key flags d1 d2 dp
17220 12 { jwin_win_proc, 0, 0, 330, 236, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Assign Compiled Script", NULL, NULL },
17221 12 { jwin_tab_proc, 6, 25, 330-12, 130, 0, 0, 0, 0, 0, 0, assignscript_tabs, NULL, (void*)assignscript_dlg },
17222 12 { jwin_button_proc, 251, 207, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
17223 12 { jwin_button_proc, 182, 207, 61, 21, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
17224 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignffc_list, NULL, NULL },
17225 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignffcscript_list, NULL, NULL },
17226 //6
17227 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17228 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignglobal_list, NULL, NULL },
17229 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignglobalscript_list, NULL, NULL },
17230 //9
17231 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17232 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignitem_list, NULL, NULL },
17233 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignitemscript_list, NULL, NULL },
17234 //12
17235 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17236 //13
17237 12 { jwin_check_proc, 22, 211, 90, 8, vc(14), vc(1), 0, 0, 1, 0, (void *) "Output ZASM code to allegro.log", NULL, NULL },
17238 12 { jwin_text_proc, 22, 178, 90, 24, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
17239 12 { d_dummy_proc, 0, 0, 0, 0, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
17240 //16
17241 12 { d_dummy_proc, 0, 0, 0, 0, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
17242 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
17243 //npc scripts
17244 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignnpc_list, NULL, NULL },
17245 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignnpcscript_list, NULL, NULL },
17246 //20
17247 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17248 //21
17249 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignlweapon_list, NULL, NULL },
17250 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignlweaponscript_list, NULL, NULL },
17251 //23
17252 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17253 //24
17254 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigneweapon_list, NULL, NULL },
17255 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigneweaponscript_list, NULL, NULL },
17256 //26
17257 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17258 //27
17259 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignplayer_list, NULL, NULL },
17260 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignplayerscript_list, NULL, NULL },
17261 //29
17262 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17263 //30
17264 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignscreen_list, NULL, NULL },
17265 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignscreenscript_list, NULL, NULL },
17266 //32
17267 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17268 //33
17269 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigndmap_list, NULL, NULL },
17270 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigndmapscript_list, NULL, NULL },
17271 //35
17272 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17273 //36
17274 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignitemsprite_list, NULL, NULL },
17275 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignitemspritescript_list, NULL, NULL },
17276 //38
17277 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17278
17279 //39
17280 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigncombo_list, NULL, NULL },
17281 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigncomboscript_list, NULL, NULL },
17282 //41
17283 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17284 12 { jwin_button_proc, 78-24, 158, 48, 16, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Script Info", NULL, NULL },
17285 12 { jwin_button_proc, 174+78-24, 158, 48, 16, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Script Info", NULL, NULL },
17286 12 { jwin_button_proc, 87+78-24, 158, 48, 16, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Clear", NULL, NULL },
17287 //45
17288 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigngeneric_list, NULL, NULL },
17289 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assigngenericscript_list, NULL, NULL },
17290 //47
17291 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17292 //48
17293 12 { jwin_abclist_proc, 10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignsubscreen_list, NULL, NULL },
17294 12 { jwin_abclist_proc, 174+10, 45, 136, 105, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0,0,0, 0, (void *)&assignsubscreenscript_list, NULL, NULL },
17295 //50
17296 12 { jwin_button_proc, 154+5, 93, 15, 10, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "<<", NULL, NULL },
17297 12 { jwin_check_proc, 22, 221, 90, 8, vc(14), vc(1), 0, 0, 1, 0, (void *) "...And output ZASM comments", NULL, NULL },
17298
17299 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
17300
17301 };
17302
17303 int32_t txtout(BITMAP* dest, const char* txt, int32_t x, int32_t y, bool disabled)
17304 {
17305 if(disabled)
17306 {
17307 gui_textout_ln(dest, font, (uint8_t*)txt, x+1, y+1, scheme[jcLIGHT], scheme[jcBOX], 0);
17308 return gui_textout_ln(dest, font, (uint8_t*)txt, x, y, scheme[jcMEDDARK], -1, 0);
17309 }
17310 else
17311 {
17312 return gui_textout_ln(dest, font, (uint8_t*)txt, x, y, scheme[jcBOXFG], scheme[jcBOX], 0);
17313 }
17314 }
17315
17316 int32_t jwin_zmeta_proc(int32_t msg, DIALOG *d, int32_t )
17317 {
17318 int32_t ret = D_O_K;
17319 ASSERT(d);
17320
17321 BITMAP* target = (msg==MSG_START ? NULL : screen);
17322 switch(msg)
17323 {
17324 case MSG_START:
17325 case MSG_DRAW:
17326 {
17327 FONT *oldfont = font;
17328
17329 if(d->dp2)
17330 {
17331 font = (FONT*)d->dp2;
17332 }
17333
17334 bool disabled = (d->flags & D_DISABLED) != 0;
17335 if(d->dp)
17336 {
17337 zasm_meta const& meta = *((zasm_meta*)d->dp);
17338 int32_t ind = -1;
17339 d->w = 0;
17340 if(!meta.valid())
17341 {
17342 d->w = txtout(target, "Invalid ZASM metadata found!", d->x, d->y, disabled);
17343 ++ind;
17344 }
17345
17346 int32_t t_w = 0;
17347 char buf[1024];
17348 memset(buf, 0, sizeof(buf));
17349 sprintf(buf, "ZASM Version: %d", meta.zasm_v);
17350 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17351 d->w = zc_max(d->w, t_w);
17352 memset(buf, 0, sizeof(buf));
17353 sprintf(buf, "Metadata Version: %d", meta.meta_v);
17354 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17355 d->w = zc_max(d->w, t_w);
17356 memset(buf, 0, sizeof(buf));
17357 sprintf(buf, "FFScript Version: %d", meta.ffscript_v);
17358 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17359 d->w = zc_max(d->w, t_w);
17360 memset(buf, 0, sizeof(buf));
17361 sprintf(buf, "Script Name: %s", meta.script_name.c_str());
17362 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17363 d->w = zc_max(d->w, t_w);
17364 memset(buf, 0, sizeof(buf));
17365 sprintf(buf, "Author: %s", meta.author.c_str());
17366 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17367 d->w = zc_max(d->w, t_w);
17368 memset(buf, 0, sizeof(buf));
17369 sprintf(buf, "Script Type: %s", get_script_name(meta.script_type).c_str());
17370 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17371 d->w = zc_max(d->w, t_w);
17372 for(auto q = 0; q < NUM_ZMETA_ATTRIBUTES; ++q)
17373 {
17374 if(!meta.attributes[q].size())
17375 continue;
17376 memset(buf, 0, sizeof(buf));
17377 sprintf(buf, "Attributes[%d]: %s", q, meta.attributes[q].c_str());
17378 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17379 d->w = zc_max(d->w, t_w);
17380 }
17381 bool indentrun = false;
17382 int32_t run_indent = txtout(NULL, "void run(", 0, 0, false);
17383 std::ostringstream oss;
17384 oss << "void run(";
17385 for(int32_t q = 0; q < 8; ++q)
17386 {
17387 if(!meta.run_idens[q].size() || meta.run_types[q] == ZMETA_NULL_TYPE) continue;
17388 if(q > 0)
17389 oss << ", ";
17390 string type_name = ZScript::getDataTypeName(meta.run_types[q]);
17391 lowerstr(type_name); //all lowercase for this output
17392 if(oss.str().size() > unsigned(indentrun ? 41 : 50))
17393 {
17394 memset(buf, 0, sizeof(buf));
17395 sprintf(buf, "%s", oss.str().c_str());
17396 t_w = txtout(target, buf, d->x + (indentrun ? run_indent : 0), d->y + ((++ind)*(text_height(font) + 3)), disabled) + (indentrun ? run_indent : 0);
17397 d->w = zc_max(d->w, t_w);
17398 oss.str("");
17399 indentrun = true;
17400 }
17401 oss << type_name.c_str() << " " << meta.run_idens[q];
17402 }
17403 oss << ");";
17404 memset(buf, 0, sizeof(buf));
17405 sprintf(buf, "%s", oss.str().c_str());
17406 t_w = txtout(target, buf, d->x + (indentrun ? run_indent : 0), d->y + ((++ind)*(text_height(font) + 3)), disabled) + (indentrun ? run_indent : 0);
17407 d->w = zc_max(d->w, t_w);
17408 memset(buf, 0, sizeof(buf));
17409 sprintf(buf, "Compiler Version: %d.%d.%d.%d", meta.compiler_v1, meta.compiler_v2, meta.compiler_v3, meta.compiler_v4);
17410 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17411 d->w = zc_max(d->w, t_w);
17412 memset(buf, 0, sizeof(buf));
17413 sprintf(buf, "Parser-generated: %s", (meta.flags & ZMETA_AUTOGEN)!=0 ? "TRUE" : "FALSE");
17414 t_w = txtout(target, buf, d->x, d->y + ((++ind)*(text_height(font) + 3)), disabled);
17415 d->w = zc_max(d->w, t_w);
17416 d->h = (++ind) * (text_height(font) + 3) -3;
17417 }
17418 else
17419 {
17420 d->w = txtout(target, "No ZASM metadata found!", d->x, d->y, disabled);
17421 d->h = text_height(font);
17422 }
17423
17424 if(d->dp3) //function trigger
17425 {
17426 typedef void (*funcType)(void);
17427 funcType func=reinterpret_cast<funcType>(d->dp3);
17428 func();
17429 }
17430
17431 font = oldfont;
17432 break;
17433 }
17434 }
17435
17436 return ret;
17437 }
17438
17439 void resize_scriptinfo_dlg();
17440
17441 static DIALOG scriptinfo_dlg[] =
17442 {
17443 // x y w h fg bg key flags d1 d2 dp
17444 { jwin_win_proc, 0, 0, 200, 150, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Script Metadata", NULL, NULL },
17445 { d_dummy_proc, 6, 25, 330-12, 130, 0, 0, 0, 0, 0, 0, assignscript_tabs, NULL, NULL },
17446 { jwin_button_proc, 70, 120, 60, 20, vc(14), vc(1), 'k', D_EXIT, 0, 0, (void *) "Done", NULL, NULL },
17447 { jwin_zmeta_proc, 50, 30, 100, 100, vc(14), vc(1), 0, 0, 0, 0, NULL, NULL, (void*)resize_scriptinfo_dlg },
17448
17449 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
17450 };
17451
17452 void resize_scriptinfo_dlg()
17453 {
17454 DIALOG *meta_proc = &scriptinfo_dlg[3], *window = &scriptinfo_dlg[0], *ok_button = &scriptinfo_dlg[2];
17455 int32_t bmargin = 15, hmargins = 30;
17456 jwin_ulalign_dialog(scriptinfo_dlg);
17457 window->w = hmargins*2 + meta_proc->w;
17458 meta_proc->x = hmargins;
17459 window->h = meta_proc->y + meta_proc->h + ok_button->h + bmargin*2;
17460 ok_button->x = (window->w/2)-(ok_button->w/2);
17461 ok_button->y = meta_proc->y + meta_proc->h + bmargin;
17462 jwin_center_dialog(scriptinfo_dlg);
17463 }
17464
17465 void showScriptInfo(zasm_meta const* meta)
17466 {
17467 scriptinfo_dlg[3].dp = (void*)meta;
17468 scriptinfo_dlg[0].dp2 = get_zc_font(font_lfont);
17469 large_dialog(scriptinfo_dlg);
17470 jwin_zmeta_proc(MSG_START,&scriptinfo_dlg[3],0); //Calculate size before calling dialog
17471 jwin_center_dialog(scriptinfo_dlg);
17472 do_zqdialog(scriptinfo_dlg,2);
17473 }
17474
17475 void write_includepaths();
17476 void call_compile_settings();
17477 int32_t onZScriptCompilerSettings()
17478 {
17479 call_compile_settings();
17480 return D_O_K;
17481 }
17482
17483 void doEditZScript()
17484 {
17485 if(do_box_edit(zScript, "ZScript Buffer", false, false))
17486 mark_save_dirty();
17487 }
17488
17489 std::string qst_cfg_header_from_path(std::string path);
17490 extern char *filepath;
17491 string get_box_cfg_hdr(int num)
17492 {
17493 if(num)
17494 return "misc";
17495 return qst_cfg_header_from_path(filepath);
17496 }
17497
17498 6 void clear_map_states()
17499 {
17500
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(map<int32_t, script_slot_data>::iterator it = ffcmap.begin();
17501 3072 it != ffcmap.end(); ++it)
17502 {
17503 3066 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17504 3066 }
17505
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 6 times.
54 for(map<int32_t, script_slot_data>::iterator it = globalmap.begin();
17506 54 it != globalmap.end(); ++it)
17507 {
17508 48 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17509 48 }
17510
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = itemmap.begin();
17511 1536 it != itemmap.end(); ++it)
17512 {
17513 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17514 1530 }
17515
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = npcmap.begin();
17516 1536 it != npcmap.end(); ++it)
17517 {
17518 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17519 1530 }
17520
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = ewpnmap.begin();
17521 1536 it != ewpnmap.end(); ++it)
17522 {
17523 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17524 1530 }
17525
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = lwpnmap.begin();
17526 1536 it != lwpnmap.end(); ++it)
17527 {
17528 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17529 1530 }
17530
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 for(map<int32_t, script_slot_data>::iterator it = playermap.begin();
17531 30 it != playermap.end(); ++it)
17532 {
17533 24 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17534 24 }
17535
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = dmapmap.begin();
17536 1536 it != dmapmap.end(); ++it)
17537 {
17538 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17539 1530 }
17540
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = screenmap.begin();
17541 1536 it != screenmap.end(); ++it)
17542 {
17543 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17544 1530 }
17545
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(map<int32_t, script_slot_data>::iterator it = itemspritemap.begin();
17546 1536 it != itemspritemap.end(); ++it)
17547 {
17548 1530 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17549 1530 }
17550
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(map<int32_t, script_slot_data>::iterator it = comboscriptmap.begin();
17551 3072 it != comboscriptmap.end(); ++it)
17552 {
17553 3066 (*it).second.format = SCRIPT_FORMAT_DEFAULT;
17554 3066 }
17555 6 }
17556
17557 void clearAssignSlotDlg()
17558 {
17559 assignscript_dlg[0].dp2 = get_zc_font(font_lfont);
17560 assignscript_dlg[4].d1 = -1;
17561 assignscript_dlg[5].d1 = -1;
17562 assignscript_dlg[7].d1 = -1;
17563 assignscript_dlg[8].d1 = -1;
17564 assignscript_dlg[10].d1 = -1;
17565 assignscript_dlg[11].d1 = -1;
17566 assignscript_dlg[13].flags = 0;
17567 }
17568
17569 void inc_script_name(string& name)
17570 {
17571 size_t pos = name.find_last_not_of("0123456789");
17572 pos = name.find_first_of("0123456789",pos);
17573 std::ostringstream oss;
17574 if(pos == string::npos)
17575 {
17576 oss << name << 2;
17577 }
17578 else
17579 {
17580 int32_t val = atoi(name.substr(pos).c_str());
17581 oss << name.substr(0,pos) << val+1;
17582 }
17583 name = oss.str();
17584 }
17585
17586 enum script_slot_type
17587 {
17588 type_ffc, type_global, type_itemdata, type_npc, type_lweapon, type_eweapon,
17589 type_hero, type_dmap, type_screen, type_itemsprite, type_combo, type_generic,
17590 type_subscreen, num_types
17591 };
17592 script_slot_type getType(ScriptType type)
17593 {
17594 switch(type)
17595 {
17596 case ScriptType::FFC: return type_ffc;
17597 case ScriptType::Global: return type_global;
17598 case ScriptType::Item: return type_itemdata;
17599 case ScriptType::NPC: return type_npc;
17600 case ScriptType::Lwpn: return type_lweapon;
17601 case ScriptType::Ewpn: return type_eweapon;
17602 case ScriptType::Hero: return type_hero;
17603 case ScriptType::DMap:
17604 case ScriptType::ScriptedActiveSubscreen:
17605 case ScriptType::ScriptedPassiveSubscreen:
17606 case ScriptType::OnMap:
17607 return type_dmap;
17608 case ScriptType::Generic: case ScriptType::GenericFrozen:
17609 return type_generic;
17610 case ScriptType::Screen: return type_screen;
17611 case ScriptType::ItemSprite: return type_itemsprite;
17612 case ScriptType::Combo: return type_combo;
17613 case ScriptType::EngineSubscreen: return type_subscreen;
17614 default: return type_ffc; //Default
17615 }
17616 }
17617 #define SLOTMSGFLAG_MISSING 0x01
17618 #define SLOTMSG_SIZE 512
17619 bool checkSkip(int32_t format, byte flags)
17620 {
17621 switch(format)
17622 {
17623 case SCRIPT_FORMAT_DEFAULT:
17624 return (flags != 0);
17625 case SCRIPT_FORMAT_INVALID:
17626 return ((flags & SLOTMSGFLAG_MISSING)==0);
17627 default: return true;
17628 }
17629 }
17630 void clearAllSlots(int32_t type, byte flags = 0)
17631 {
17632 bound(type,0,num_types-1);
17633 switch(type)
17634 {
17635 case type_ffc:
17636 {
17637 for(int32_t q = 0; q < NUMSCRIPTFFC-1; ++q)
17638 {
17639 if(checkSkip(ffcmap[q].format, flags)) continue;
17640 ffcmap[q].scriptname = "";
17641 ffcmap[q].format = SCRIPT_FORMAT_DEFAULT;
17642 }
17643 break;
17644 }
17645 case type_global:
17646 {
17647 //Start at 1 to not clear Init
17648 for(int32_t q = 1; q < NUMSCRIPTGLOBAL; ++q)
17649 {
17650 if(checkSkip(globalmap[q].format, flags)) continue;
17651 globalmap[q].scriptname = "";
17652 globalmap[q].format = SCRIPT_FORMAT_DEFAULT;
17653 }
17654 break;
17655 }
17656 case type_itemdata:
17657 {
17658 for(int32_t q = 0; q < NUMSCRIPTITEM-1; ++q)
17659 {
17660 if(checkSkip(itemmap[q].format, flags)) continue;
17661 itemmap[q].scriptname = "";
17662 itemmap[q].format = SCRIPT_FORMAT_DEFAULT;
17663 }
17664 break;
17665 }
17666 case type_npc:
17667 {
17668 for(int32_t q = 0; q < NUMSCRIPTGUYS-1; ++q)
17669 {
17670 if(checkSkip(npcmap[q].format, flags)) continue;
17671 npcmap[q].scriptname = "";
17672 npcmap[q].format = SCRIPT_FORMAT_DEFAULT;
17673 }
17674 break;
17675 }
17676 case type_lweapon:
17677 {
17678 for(int32_t q = 0; q < NUMSCRIPTWEAPONS-1; ++q)
17679 {
17680 if(checkSkip(lwpnmap[q].format, flags)) continue;
17681 lwpnmap[q].scriptname = "";
17682 lwpnmap[q].format = SCRIPT_FORMAT_DEFAULT;
17683 }
17684 break;
17685 }
17686 case type_eweapon:
17687 {
17688 for(int32_t q = 0; q < NUMSCRIPTWEAPONS-1; ++q)
17689 {
17690 if(checkSkip(ewpnmap[q].format, flags)) continue;
17691 ewpnmap[q].scriptname = "";
17692 ewpnmap[q].format = SCRIPT_FORMAT_DEFAULT;
17693 }
17694 break;
17695 }
17696 case type_hero:
17697 {
17698 for(int32_t q = 0; q < NUMSCRIPTHERO-1; ++q)
17699 {
17700 if(checkSkip(playermap[q].format, flags)) continue;
17701 playermap[q].scriptname = "";
17702 playermap[q].format = SCRIPT_FORMAT_DEFAULT;
17703 }
17704 break;
17705 }
17706 case type_dmap:
17707 {
17708 for(int32_t q = 0; q < NUMSCRIPTSDMAP-1; ++q)
17709 {
17710 if(checkSkip(dmapmap[q].format, flags)) continue;
17711 dmapmap[q].scriptname = "";
17712 dmapmap[q].format = SCRIPT_FORMAT_DEFAULT;
17713 }
17714 break;
17715 }
17716 case type_screen:
17717 {
17718 for(int32_t q = 0; q < NUMSCRIPTSCREEN-1; ++q)
17719 {
17720 if(checkSkip(screenmap[q].format, flags)) continue;
17721 screenmap[q].scriptname = "";
17722 screenmap[q].format = SCRIPT_FORMAT_DEFAULT;
17723 }
17724 break;
17725 }
17726 case type_itemsprite:
17727 {
17728 for(int32_t q = 0; q < NUMSCRIPTSITEMSPRITE-1; ++q)
17729 {
17730 if(checkSkip(itemspritemap[q].format, flags)) continue;
17731 itemspritemap[q].scriptname = "";
17732 itemspritemap[q].format = SCRIPT_FORMAT_DEFAULT;
17733 }
17734 break;
17735 }
17736 case type_combo:
17737 {
17738 for(int32_t q = 0; q < NUMSCRIPTSCOMBODATA-1; ++q)
17739 {
17740 if(checkSkip(comboscriptmap[q].format, flags)) continue;
17741 comboscriptmap[q].scriptname = "";
17742 comboscriptmap[q].format = SCRIPT_FORMAT_DEFAULT;
17743 }
17744 break;
17745 }
17746 case type_generic:
17747 {
17748 for(int32_t q = 0; q < NUMSCRIPTSGENERIC-1; ++q)
17749 {
17750 if(checkSkip(genericmap[q].format, flags)) continue;
17751 genericmap[q].scriptname = "";
17752 genericmap[q].format = SCRIPT_FORMAT_DEFAULT;
17753 }
17754 break;
17755 }
17756 case type_subscreen:
17757 {
17758 for(int32_t q = 0; q < NUMSCRIPTSSUBSCREEN-1; ++q)
17759 {
17760 if(checkSkip(subscreenmap[q].format, flags)) continue;
17761 subscreenmap[q].scriptname = "";
17762 subscreenmap[q].format = SCRIPT_FORMAT_DEFAULT;
17763 }
17764 break;
17765 }
17766 }
17767 }
17768
17769 static bool doslots_log_output = false, doslots_comment_output = true;
17770 6 void setup_scriptslot_dlg(char* buf, byte flags)
17771 {
17772 //{ Set up the textbox at the bottom, and auto-resize height based on it
17773 6 int32_t prev_height = assignscript_dlg[14].h;
17774 6 memset(buf, 0, SLOTMSG_SIZE);
17775 //
17776 6 strcpy(buf, "Slots with matching names have been updated.\n");
17777
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if(flags & SLOTMSGFLAG_MISSING)
17778 3 strcat(buf,"Scripts prefixed with '--' were not found, and will not function.\n");
17779 6 strcat(buf,"Global scripts named 'Init' will be appended to '~Init'");
17780 //
17781
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 SETFLAG(assignscript_dlg[13].flags, D_SELECTED, doslots_log_output);
17782
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 SETFLAG(assignscript_dlg[51].flags, D_SELECTED, doslots_comment_output);
17783 6 assignscript_dlg[14].dp = buf;
17784 6 object_message(&assignscript_dlg[14], MSG_START, 0); //Set the width/height
17785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(int32_t diff = assignscript_dlg[14].h - prev_height) //resize dlg
17786 {
17787 6 int32_t prev_bottom = assignscript_dlg[14].y + prev_height;
17788
2/2
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 6 times.
312 for(int32_t q = 1; assignscript_dlg[q].proc; ++q)
17789 {
17790
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 300 times.
306 if(q==14) continue; //Don't change self
17791
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 24 times.
300 if(assignscript_dlg[q].y < prev_bottom) continue; //above proc
17792 24 assignscript_dlg[q].y += diff;
17793 24 }
17794 6 assignscript_dlg[0].h += diff;
17795 6 jwin_center_dialog(assignscript_dlg);
17796 6 }
17797 //}
17798 6 }
17799
17800 std::string global_slotnames[NUMSCRIPTGLOBAL] = {
17801 "Init",
17802 "Active",
17803 "onExit",
17804 "onSaveLoad",
17805 "onLaunch",
17806 "onContGame",
17807 "onF6Menu",
17808 "onSave",
17809 };
17810 std::string player_slotnames[NUMSCRIPTHERO-1] = {
17811 "Init",
17812 "Active",
17813 "onDeath",
17814 "onWin",
17815 };
17816 6 byte reload_scripts(map<string, disassembled_script_data> &scripts)
17817 {
17818 6 byte slotflags = 0;
17819 char temp[100];
17820
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(int32_t i = 0; i < NUMSCRIPTFFC-1; i++)
17821 {
17822
2/2
✓ Branch 0 taken 2987 times.
✓ Branch 1 taken 79 times.
3066 if(ffcmap[i].isEmpty())
17823 2987 sprintf(temp, "Slot %d:", i+1);
17824 else
17825 {
17826 79 sprintf(temp, "Slot %d:", i+1);
17827
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 6 times.
79 if(scripts.find(ffcmap[i].scriptname) != scripts.end())
17828 73 ffcmap[i].format = SCRIPT_FORMAT_DEFAULT;
17829 else // Previously loaded script not found
17830 {
17831 6 ffcmap[i].format = SCRIPT_FORMAT_INVALID;
17832 6 slotflags |= SLOTMSGFLAG_MISSING;
17833 }
17834 }
17835 3066 ffcmap[i].slotname = temp;
17836 3066 ffcmap[i].update();
17837 3066 }
17838
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 6 times.
54 for(int32_t i = 0; i < NUMSCRIPTGLOBAL; i++)
17839 {
17840
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 globalmap[i].slotname=fmt::format("{}:",global_slotnames[i]);
17841
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 11 times.
48 if(!globalmap[i].isEmpty())
17842 {
17843
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 if(scripts.find(globalmap[i].scriptname) != scripts.end() || globalmap[i].scriptname == "~Init")
17844 11 globalmap[i].format = SCRIPT_FORMAT_DEFAULT;
17845 else // Unloaded
17846 {
17847 globalmap[i].format = SCRIPT_FORMAT_INVALID;
17848 slotflags |= SLOTMSGFLAG_MISSING;
17849 }
17850 11 }
17851 48 globalmap[i].update();
17852 48 }
17853
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTITEM-1; i++)
17854 {
17855
2/2
✓ Branch 0 taken 1517 times.
✓ Branch 1 taken 13 times.
1530 if(itemmap[i].isEmpty())
17856 1517 sprintf(temp, "Slot %d:", i+1);
17857 else
17858 {
17859 13 sprintf(temp, "Slot %d:", i+1);
17860
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if(scripts.find(itemmap[i].scriptname) != scripts.end())
17861 13 itemmap[i].format = SCRIPT_FORMAT_DEFAULT;
17862 else // Previously loaded script not found
17863 {
17864 itemmap[i].format = SCRIPT_FORMAT_INVALID;
17865 slotflags |= SLOTMSGFLAG_MISSING;
17866 }
17867 }
17868 1530 itemmap[i].slotname = temp;
17869 1530 itemmap[i].update();
17870 1530 }
17871
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTGUYS-1; i++)
17872 {
17873
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 if(npcmap[i].isEmpty())
17874 1530 sprintf(temp, "Slot %d:", i+1);
17875 else
17876 {
17877 sprintf(temp, "Slot %d:", i+1);
17878 if(scripts.find(npcmap[i].scriptname) != scripts.end())
17879 npcmap[i].format = SCRIPT_FORMAT_DEFAULT;
17880 else // Previously loaded script not found
17881 {
17882 npcmap[i].format = SCRIPT_FORMAT_INVALID;
17883 slotflags |= SLOTMSGFLAG_MISSING;
17884 }
17885 }
17886 1530 npcmap[i].slotname = temp;
17887 1530 npcmap[i].update();
17888 1530 }
17889
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTWEAPONS-1; i++)
17890 {
17891
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 if(ewpnmap[i].isEmpty())
17892 1530 sprintf(temp, "Slot %d:", i+1);
17893 else
17894 {
17895 sprintf(temp, "Slot %d:", i+1);
17896 if(scripts.find(ewpnmap[i].scriptname) != scripts.end())
17897 ewpnmap[i].format = SCRIPT_FORMAT_DEFAULT;
17898 else // Previously loaded script not found
17899 {
17900 ewpnmap[i].format = SCRIPT_FORMAT_INVALID;
17901 slotflags |= SLOTMSGFLAG_MISSING;
17902 }
17903 }
17904 1530 ewpnmap[i].slotname = temp;
17905 1530 ewpnmap[i].update();
17906 1530 }
17907
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTWEAPONS-1; i++)
17908 {
17909
2/2
✓ Branch 0 taken 1529 times.
✓ Branch 1 taken 1 times.
1530 if(lwpnmap[i].isEmpty())
17910 1529 sprintf(temp, "Slot %d:", i+1);
17911 else
17912 {
17913 1 sprintf(temp, "Slot %d:", i+1);
17914
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(scripts.find(lwpnmap[i].scriptname) != scripts.end())
17915 1 lwpnmap[i].format = SCRIPT_FORMAT_DEFAULT;
17916 else // Previously loaded script not found
17917 {
17918 lwpnmap[i].format = SCRIPT_FORMAT_INVALID;
17919 slotflags |= SLOTMSGFLAG_MISSING;
17920 }
17921 }
17922 1530 lwpnmap[i].slotname = temp;
17923 1530 lwpnmap[i].update();
17924 1530 }
17925
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 for(int32_t i = 0; i < NUMSCRIPTHERO-1; i++)
17926 {
17927
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 playermap[i].slotname=fmt::format("{}:",player_slotnames[i]);
17928
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if(!playermap[i].isEmpty())
17929 {
17930 if(scripts.find(playermap[i].scriptname) != scripts.end())
17931 playermap[i].format = SCRIPT_FORMAT_DEFAULT;
17932 else // Unloaded
17933 {
17934 playermap[i].format = SCRIPT_FORMAT_INVALID;
17935 slotflags |= SLOTMSGFLAG_MISSING;
17936 }
17937 }
17938 24 playermap[i].update();
17939 24 }
17940
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTSCREEN-1; i++)
17941 {
17942
2/2
✓ Branch 0 taken 1528 times.
✓ Branch 1 taken 2 times.
1530 if(screenmap[i].isEmpty())
17943 1528 sprintf(temp, "Slot %d:", i+1);
17944 else
17945 {
17946 2 sprintf(temp, "Slot %d:", i+1);
17947
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if(scripts.find(screenmap[i].scriptname) != scripts.end())
17948 2 screenmap[i].format = SCRIPT_FORMAT_DEFAULT;
17949 else // Previously loaded script not found
17950 {
17951 screenmap[i].format = SCRIPT_FORMAT_INVALID;
17952 slotflags |= SLOTMSGFLAG_MISSING;
17953 }
17954 }
17955 1530 screenmap[i].slotname = temp;
17956 1530 screenmap[i].update();
17957 1530 }
17958
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTSDMAP-1; i++)
17959 {
17960
2/2
✓ Branch 0 taken 1525 times.
✓ Branch 1 taken 5 times.
1530 if(dmapmap[i].isEmpty())
17961 1525 sprintf(temp, "Slot %d:", i+1);
17962 else
17963 {
17964 5 sprintf(temp, "Slot %d:", i+1);
17965
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if(scripts.find(dmapmap[i].scriptname) != scripts.end())
17966 5 dmapmap[i].format = SCRIPT_FORMAT_DEFAULT;
17967 else // Previously loaded script not found
17968 {
17969 dmapmap[i].format = SCRIPT_FORMAT_INVALID;
17970 slotflags |= SLOTMSGFLAG_MISSING;
17971 }
17972 }
17973 1530 dmapmap[i].slotname = temp;
17974 1530 dmapmap[i].update();
17975 1530 }
17976
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTSITEMSPRITE-1; i++)
17977 {
17978
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 if(itemspritemap[i].isEmpty())
17979 1530 sprintf(temp, "Slot %d:", i+1);
17980 else
17981 {
17982 sprintf(temp, "Slot %d:", i+1);
17983 if(scripts.find(itemspritemap[i].scriptname) != scripts.end())
17984 itemspritemap[i].format = SCRIPT_FORMAT_DEFAULT;
17985 else // Previously loaded script not found
17986 {
17987 itemspritemap[i].format = SCRIPT_FORMAT_INVALID;
17988 slotflags |= SLOTMSGFLAG_MISSING;
17989 }
17990 }
17991 1530 itemspritemap[i].slotname = temp;
17992 1530 itemspritemap[i].update();
17993 1530 }
17994
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(int32_t i = 0; i < NUMSCRIPTSCOMBODATA-1; i++)
17995 {
17996
1/2
✓ Branch 0 taken 3066 times.
✗ Branch 1 not taken.
3066 if(comboscriptmap[i].isEmpty())
17997 3066 sprintf(temp, "Slot %d:", i+1);
17998 else
17999 {
18000 sprintf(temp, "Slot %d:", i+1);
18001 if(scripts.find(comboscriptmap[i].scriptname) != scripts.end())
18002 comboscriptmap[i].format = SCRIPT_FORMAT_DEFAULT;
18003 else // Previously loaded script not found
18004 {
18005 comboscriptmap[i].format = SCRIPT_FORMAT_INVALID;
18006 slotflags |= SLOTMSGFLAG_MISSING;
18007 }
18008 }
18009 3066 comboscriptmap[i].slotname = temp;
18010 3066 comboscriptmap[i].update();
18011 3066 }
18012
2/2
✓ Branch 0 taken 3066 times.
✓ Branch 1 taken 6 times.
3072 for(int32_t i = 0; i < NUMSCRIPTSGENERIC-1; i++)
18013 {
18014
2/2
✓ Branch 0 taken 3044 times.
✓ Branch 1 taken 22 times.
3066 if(genericmap[i].isEmpty())
18015 3044 sprintf(temp, "Slot %d:", i+1);
18016 else
18017 {
18018 22 sprintf(temp, "Slot %d:", i+1);
18019
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 times.
22 if(scripts.find(genericmap[i].scriptname) != scripts.end())
18020 21 genericmap[i].format = SCRIPT_FORMAT_DEFAULT;
18021 else // Previously loaded script not found
18022 {
18023 1 genericmap[i].format = SCRIPT_FORMAT_INVALID;
18024 1 slotflags |= SLOTMSGFLAG_MISSING;
18025 }
18026 }
18027 3066 genericmap[i].slotname = temp;
18028 3066 genericmap[i].update();
18029 3066 }
18030
2/2
✓ Branch 0 taken 1530 times.
✓ Branch 1 taken 6 times.
1536 for(int32_t i = 0; i < NUMSCRIPTSSUBSCREEN-1; i++)
18031 {
18032
1/2
✓ Branch 0 taken 1530 times.
✗ Branch 1 not taken.
1530 if(subscreenmap[i].isEmpty())
18033 1530 sprintf(temp, "Slot %d:", i+1);
18034 else
18035 {
18036 sprintf(temp, "Slot %d:", i+1);
18037 if(scripts.find(subscreenmap[i].scriptname) != scripts.end())
18038 subscreenmap[i].format = SCRIPT_FORMAT_DEFAULT;
18039 else // Previously loaded script not found
18040 {
18041 subscreenmap[i].format = SCRIPT_FORMAT_INVALID;
18042 slotflags |= SLOTMSGFLAG_MISSING;
18043 }
18044 }
18045 1530 subscreenmap[i].slotname = temp;
18046 1530 subscreenmap[i].update();
18047 1530 }
18048 6 return slotflags;
18049 }
18050
18051 void doClearSlots(byte* flags);
18052
18053 static map<string, disassembled_script_data> *doslot_scripts = nullptr;
18054 21510 bool handle_slot(script_slot_data& slotdata, script_data* scriptdata)
18055 {
18056
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 21384 times.
21510 if(slotdata.hasScriptData())
18057 {
18058 126 auto& data = (*doslot_scripts)[slotdata.scriptname];
18059 126 scriptdata->meta = data.meta;
18060 126 scriptdata->pc = data.pc;
18061 126 scriptdata->end_pc = data.end_pc;
18062 126 scriptdata->zasm_script = zasm_scripts[0];
18063 126 }
18064
1/2
✓ Branch 0 taken 21384 times.
✗ Branch 1 not taken.
21384 else if(scriptdata)
18065 {
18066 21384 scriptdata->zasm_script = nullptr;
18067 21384 scriptdata->meta.zero();
18068 21384 scriptdata->pc = 0;
18069 21384 scriptdata->end_pc = 0;
18070 21384 }
18071 21510 return true;
18072 }
18073 78 bool handle_slot_map(map<int32_t, script_slot_data>& mp, int offs, script_data** scriptdata)
18074 {
18075
2/2
✓ Branch 0 taken 21510 times.
✓ Branch 1 taken 78 times.
21588 for(auto it = mp.begin(); it != mp.end(); it++)
18076 {
18077
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21510 times.
21510 if(!handle_slot(it->second, scriptdata[it->first + offs]))
18078 return false;
18079 21510 }
18080 78 return true;
18081 78 }
18082
18083 void smart_slot_named(map<string, disassembled_script_data> &scripts,
18084 vector<string> const& scriptnames, map<int32_t, script_slot_data>& mp,
18085 std::string* slotnames, int slotstart, int slotend)
18086 {
18087 for(int q = slotstart; q < slotend; ++q)
18088 {
18089 auto& lval = mp[q];
18090 if(!lval.isEmpty())
18091 continue; //occupied, leave alone
18092 bool done = false;
18093 if(!done) //Check case-sensitive
18094 for(size_t rind = 0; rind < scriptnames.size(); ++rind)
18095 {
18096 auto const& rval = scriptnames[rind];
18097 if(rval == "<none>") continue;
18098 if(rval == slotnames[q])
18099 { //Perfect match
18100 lval.updateName(rval);
18101 lval.format = scripts[lval.scriptname].format;
18102 done = true;
18103 break;
18104 }
18105 }
18106 if(!done) //Check case-insensitive
18107 for(size_t rind = 0; rind < scriptnames.size(); ++rind)
18108 {
18109 auto const& rval = scriptnames[rind];
18110 if(rval == "<none>") continue;
18111 string lc_rv = rval, lc_slot = slotnames[q];
18112 lowerstr(lc_rv);
18113 lowerstr(lc_slot);
18114 if(lc_rv == lc_slot)
18115 { //Insensitive match
18116 lval.updateName(rval);
18117 lval.format = scripts[lval.scriptname].format;
18118 break;
18119 }
18120 }
18121 }
18122 }
18123 void smart_slot_type(map<string, disassembled_script_data> &scripts,
18124 vector<string> const& scriptnames, map<int32_t, script_slot_data>& mp,
18125 int slotcount)
18126 {
18127 for(size_t rind = 0; rind < scriptnames.size(); ++rind)
18128 {
18129 auto const& rval = scriptnames[rind];
18130 if(rval == "<none>") continue;
18131 script_slot_data* first_open_slot = nullptr;
18132 bool done = false;
18133 for(int q = 0; q < slotcount; ++q)
18134 {
18135 auto& lval = mp[q];
18136 if(lval.isEmpty())
18137 {
18138 if(!first_open_slot)
18139 first_open_slot = &lval;
18140 }
18141 else if(lval.scriptname == rval)
18142 {
18143 done = true;
18144 break;
18145 }
18146 }
18147 if(!done)
18148 {
18149 if(!first_open_slot)
18150 break; //no slots left to assign to!
18151 first_open_slot->updateName(rval);
18152 first_open_slot->format = scripts[first_open_slot->scriptname].format;
18153 }
18154 }
18155 }
18156
18157 6 bool do_slots(vector<shared_ptr<ZScript::Opcode>> const& zasm,
18158 map<string, disassembled_script_data> &scripts, int assign_mode)
18159 {
18160 6 large_dialog(assignscript_dlg);
18161 6 int32_t ret = 3;
18162 6 char slots_msg[SLOTMSG_SIZE] = {0};
18163 6 byte slotflags = reload_scripts(scripts);
18164 6 setup_scriptslot_dlg(slots_msg, slotflags);
18165 6 bool retval = false;
18166
18167 6 popup_zqdialog_start();
18168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 while(!assign_mode)
18169 {
18170 slotflags = reload_scripts(scripts);
18171 ret = do_zqdialog(assignscript_dlg, ret);
18172
18173 switch(ret)
18174 {
18175 case 0:
18176 case 2:
18177 //Cancel
18178 goto exit_do_slots;
18179
18180 case 3: goto auto_do_slots;
18181
18182 case 6:
18183 //<<, FFC
18184 {
18185 int32_t lind = assignscript_dlg[4].d1;
18186 int32_t rind = assignscript_dlg[5].d1;
18187
18188 if(lind < 0 || rind < 0)
18189 break;
18190
18191 if(asffcscripts[rind] == "<none>")
18192 {
18193 ffcmap[lind].scriptname = "";
18194 ffcmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18195 }
18196 else
18197 {
18198 ffcmap[lind].updateName(asffcscripts[rind]);
18199 ffcmap[lind].format = scripts[ffcmap[lind].scriptname].format;
18200 }
18201
18202 break;
18203 }
18204 case 9:
18205 //<<, Global
18206 {
18207 int32_t lind = assignscript_dlg[7].d1;
18208 int32_t rind = assignscript_dlg[8].d1;
18209
18210 if(lind < 0 || rind < 0)
18211 break;
18212
18213 if(lind == 0)
18214 {
18215 displayinfo("Error","ZScript reserves this slot.");
18216 break;
18217 }
18218
18219 if(asglobalscripts[rind] == "<none>")
18220 {
18221 globalmap[lind].scriptname = "";
18222 globalmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18223 }
18224 else
18225 {
18226 globalmap[lind].updateName(asglobalscripts[rind]);
18227 globalmap[lind].format = scripts[globalmap[lind].scriptname].format;
18228 }
18229
18230 break;
18231 }
18232 case 12:
18233 //<<, ITEM
18234 {
18235 int32_t lind = assignscript_dlg[10].d1;
18236 int32_t rind = assignscript_dlg[11].d1;
18237
18238 if(lind < 0 || rind < 0)
18239 break;
18240
18241 if(asitemscripts[rind] == "<none>")
18242 {
18243 itemmap[lind].scriptname = "";
18244 itemmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18245 }
18246 else
18247 {
18248 itemmap[lind].updateName(asitemscripts[rind]);
18249 itemmap[lind].format = scripts[itemmap[lind].scriptname].format;
18250 }
18251
18252 break;
18253 }
18254 case 20:
18255 //<<, NPC
18256 {
18257 int32_t lind = assignscript_dlg[18].d1;
18258 int32_t rind = assignscript_dlg[19].d1;
18259
18260 if(lind < 0 || rind < 0)
18261 break;
18262
18263 if(asnpcscripts[rind] == "<none>")
18264 {
18265 npcmap[lind].scriptname = "";
18266 npcmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18267 }
18268 else
18269 {
18270 npcmap[lind].updateName(asnpcscripts[rind]);
18271 npcmap[lind].format = scripts[npcmap[lind].scriptname].format;
18272 }
18273
18274 break;
18275 }
18276 case 23:
18277 //<<, LWeapon
18278 {
18279 int32_t lind = assignscript_dlg[21].d1;
18280 int32_t rind = assignscript_dlg[22].d1;
18281
18282 if(lind < 0 || rind < 0)
18283 break;
18284
18285 if(aslweaponscripts[rind] == "<none>")
18286 {
18287 lwpnmap[lind].scriptname = "";
18288 lwpnmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18289 }
18290 else
18291 {
18292 lwpnmap[lind].updateName(aslweaponscripts[rind]);
18293 lwpnmap[lind].format = scripts[lwpnmap[lind].scriptname].format;
18294 }
18295
18296 break;
18297 }
18298 case 26:
18299 //<<, EWeapon
18300 {
18301 int32_t lind = assignscript_dlg[24].d1;
18302 int32_t rind = assignscript_dlg[25].d1;
18303
18304 if(lind < 0 || rind < 0)
18305 break;
18306
18307 if(aseweaponscripts[rind] == "<none>")
18308 {
18309 ewpnmap[lind].scriptname = "";
18310 ewpnmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18311 }
18312 else
18313 {
18314 ewpnmap[lind].updateName(aseweaponscripts[rind]);
18315 ewpnmap[lind].format = scripts[ewpnmap[lind].scriptname].format;
18316 }
18317
18318 break;
18319 }
18320 case 29:
18321 //<<, Hero
18322 {
18323 int32_t lind = assignscript_dlg[27].d1;
18324 int32_t rind = assignscript_dlg[28].d1;
18325
18326 if(lind < 0 || rind < 0)
18327 break;
18328
18329 if(asplayerscripts[rind] == "<none>")
18330 {
18331 playermap[lind].scriptname = "";
18332 playermap[lind].format = SCRIPT_FORMAT_DEFAULT;
18333 }
18334 else
18335 {
18336 playermap[lind].updateName(asplayerscripts[rind]);
18337 playermap[lind].format = scripts[playermap[lind].scriptname].format;
18338 }
18339
18340 break;
18341 }
18342 case 32:
18343 //<<, Screendata
18344 {
18345 int32_t lind = assignscript_dlg[30].d1;
18346 int32_t rind = assignscript_dlg[31].d1;
18347
18348 if(lind < 0 || rind < 0)
18349 break;
18350
18351 if(asscreenscripts[rind] == "<none>")
18352 {
18353 screenmap[lind].scriptname = "";
18354 screenmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18355 }
18356 else
18357 {
18358 screenmap[lind].updateName(asscreenscripts[rind]);
18359 screenmap[lind].format = scripts[screenmap[lind].scriptname].format;
18360 }
18361
18362 break;
18363 }
18364 case 35:
18365 //<<, dmapdata
18366 {
18367 int32_t lind = assignscript_dlg[33].d1;
18368 int32_t rind = assignscript_dlg[34].d1;
18369
18370 if(lind < 0 || rind < 0)
18371 break;
18372
18373 if(asdmapscripts[rind] == "<none>")
18374 {
18375 dmapmap[lind].scriptname = "";
18376 dmapmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18377 }
18378 else
18379 {
18380 dmapmap[lind].updateName(asdmapscripts[rind]);
18381 dmapmap[lind].format = scripts[dmapmap[lind].scriptname].format;
18382 }
18383
18384 break;
18385 }
18386 case 38:
18387 //<<, itemsprite
18388 {
18389 int32_t lind = assignscript_dlg[36].d1;
18390 int32_t rind = assignscript_dlg[37].d1;
18391
18392 if(lind < 0 || rind < 0)
18393 break;
18394
18395 if(asitemspritescripts[rind] == "<none>")
18396 {
18397 itemspritemap[lind].scriptname = "";
18398 itemspritemap[lind].format = SCRIPT_FORMAT_DEFAULT;
18399 }
18400 else
18401 {
18402 itemspritemap[lind].updateName(asitemspritescripts[rind]);
18403 itemspritemap[lind].format = scripts[itemspritemap[lind].scriptname].format;
18404 }
18405
18406 break;
18407 }
18408 case 41:
18409 //<<, comboscript
18410 {
18411 int32_t lind = assignscript_dlg[39].d1;
18412 int32_t rind = assignscript_dlg[40].d1;
18413
18414 if(lind < 0 || rind < 0)
18415 break;
18416
18417 if(ascomboscripts[rind] == "<none>")
18418 {
18419 comboscriptmap[lind].scriptname = "";
18420 comboscriptmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18421 }
18422 else
18423 {
18424 comboscriptmap[lind].updateName(ascomboscripts[rind]);
18425 comboscriptmap[lind].format = scripts[comboscriptmap[lind].scriptname].format;
18426 }
18427
18428 break;
18429 }
18430 case 47:
18431 //<<, generic script
18432 {
18433 int32_t lind = assignscript_dlg[45].d1;
18434 int32_t rind = assignscript_dlg[46].d1;
18435
18436 if(lind < 0 || rind < 0)
18437 break;
18438
18439 if(asgenericscripts[rind] == "<none>")
18440 {
18441 genericmap[lind].scriptname = "";
18442 genericmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18443 }
18444 else
18445 {
18446 genericmap[lind].updateName(asgenericscripts[rind]);
18447 genericmap[lind].format = scripts[genericmap[lind].scriptname].format;
18448 }
18449
18450 break;
18451 }
18452 case 50:
18453 //<<, subscreen script
18454 {
18455 int32_t lind = assignscript_dlg[48].d1;
18456 int32_t rind = assignscript_dlg[49].d1;
18457
18458 if(lind < 0 || rind < 0)
18459 break;
18460
18461 if(assubscreenscripts[rind] == "<none>")
18462 {
18463 subscreenmap[lind].scriptname = "";
18464 subscreenmap[lind].format = SCRIPT_FORMAT_DEFAULT;
18465 }
18466 else
18467 {
18468 subscreenmap[lind].updateName(assubscreenscripts[rind]);
18469 subscreenmap[lind].format = scripts[subscreenmap[lind].scriptname].format;
18470 }
18471
18472 break;
18473 }
18474
18475 case 42:
18476 //Script Info, information
18477 {
18478 disassembled_script_data* target = nullptr;
18479 switch(get_selected_tab((TABPANEL*)assignscript_dlg[1].dp))
18480 {
18481 default:
18482 case 0: //FFC
18483 {
18484 int32_t id = assignscript_dlg[4].d1;
18485 if(id > -1 && ffcmap[id].hasScriptData())
18486 {
18487 target = &(scripts[ffcmap[id].scriptname]);
18488 }
18489 break;
18490 }
18491 case 1: //Global
18492 {
18493 int32_t id = assignscript_dlg[7].d1;
18494 if(id > -1 && globalmap[id].hasScriptData())
18495 {
18496 target = &(scripts[globalmap[id].scriptname]);
18497 }
18498 break;
18499 }
18500 case 2: //Item
18501 {
18502 int32_t id = assignscript_dlg[10].d1;
18503 if(id > -1 && itemmap[id].hasScriptData())
18504 {
18505 target = &(scripts[itemmap[id].scriptname]);
18506 }
18507 break;
18508 }
18509 case 3: //npc
18510 {
18511 int32_t id = assignscript_dlg[19].d1;
18512 if(id > -1 && npcmap[id].hasScriptData())
18513 {
18514 target = &(scripts[npcmap[id].scriptname]);
18515 }
18516 break;
18517 }
18518 case 4: //lweapon
18519 {
18520 int32_t id = assignscript_dlg[21].d1;
18521 if(id > -1 && lwpnmap[id].hasScriptData())
18522 {
18523 target = &(scripts[lwpnmap[id].scriptname]);
18524 }
18525 break;
18526 }
18527 case 5: //eweapon
18528 {
18529 int32_t id = assignscript_dlg[24].d1;
18530 if(id > -1 && ewpnmap[id].hasScriptData())
18531 {
18532 target = &(scripts[ewpnmap[id].scriptname]);
18533 }
18534 break;
18535 }
18536 case 6: //hero
18537 {
18538 int32_t id = assignscript_dlg[27].d1;
18539 if(id > -1 && playermap[id].hasScriptData())
18540 {
18541 target = &(scripts[playermap[id].scriptname]);
18542 }
18543 break;
18544 }
18545 case 7: //dmap
18546 {
18547 int32_t id = assignscript_dlg[33].d1;
18548 if(id > -1 && dmapmap[id].hasScriptData())
18549 {
18550 target = &(scripts[dmapmap[id].scriptname]);
18551 }
18552 break;
18553 }
18554 case 8: //screen
18555 {
18556 int32_t id = assignscript_dlg[30].d1;
18557 if(id > -1 && screenmap[id].hasScriptData())
18558 {
18559 target = &(scripts[screenmap[id].scriptname]);
18560 }
18561 break;
18562 }
18563 case 9: //itemsprite
18564 {
18565 int32_t id = assignscript_dlg[36].d1;
18566 if(id > -1 && itemspritemap[id].hasScriptData())
18567 {
18568 target = &(scripts[itemspritemap[id].scriptname]);
18569 }
18570 break;
18571 }
18572 case 10: //combo
18573 {
18574 int32_t id = assignscript_dlg[39].d1;
18575 if(id > -1 && comboscriptmap[id].hasScriptData())
18576 {
18577 target = &(scripts[comboscriptmap[id].scriptname]);
18578 }
18579 break;
18580 }
18581 case 11: //Generic
18582 {
18583 int32_t id = assignscript_dlg[45].d1;
18584 if(id > -1 && genericmap[id].hasScriptData())
18585 {
18586 target = &(scripts[genericmap[id].scriptname]);
18587 }
18588 break;
18589 }
18590 case 12: //Subscreen
18591 {
18592 int32_t id = assignscript_dlg[48].d1;
18593 if(id > -1 && subscreenmap[id].hasScriptData())
18594 {
18595 target = &(scripts[subscreenmap[id].scriptname]);
18596 }
18597 break;
18598 }
18599 }
18600 if(target)
18601 showScriptInfo(&target->meta);
18602 break;
18603 }
18604
18605 case 43:
18606 //Script Info, information
18607 {
18608 disassembled_script_data* target = NULL;
18609 switch(get_selected_tab((TABPANEL*)assignscript_dlg[1].dp))
18610 {
18611 default:
18612 case 0: //FFC
18613 {
18614 int32_t id = assignscript_dlg[5].d1;
18615 if(id < 0 || asffcscripts[id] == "<none>" || asffcscripts[id].at(0) == '-') break;
18616 target = &(scripts[asffcscripts[id]]);
18617 break;
18618 }
18619 case 1: //Global
18620 {
18621 int32_t id = assignscript_dlg[8].d1;
18622 if(id < 0 || asglobalscripts[id] == "<none>" || asglobalscripts[id].at(0) == '-') break;
18623 target = &(scripts[asglobalscripts[id]]);
18624 break;
18625 }
18626 case 2: //Item
18627 {
18628 int32_t id = assignscript_dlg[11].d1;
18629 if(id < 0 || asitemscripts[id] == "<none>" || asitemscripts[id].at(0) == '-') break;
18630 target = &(scripts[asitemscripts[id]]);
18631 break;
18632 }
18633 case 3: //npc
18634 {
18635 int32_t id = assignscript_dlg[20].d1;
18636 if(id < 0 || asnpcscripts[id] == "<none>" || asnpcscripts[id].at(0) == '-') break;
18637 target = &(scripts[asnpcscripts[id]]);
18638 break;
18639 }
18640 case 4: //lweapon
18641 {
18642 int32_t id = assignscript_dlg[22].d1;
18643 if(id < 0 || aslweaponscripts[id] == "<none>" || aslweaponscripts[id].at(0) == '-') break;
18644 target = &(scripts[aslweaponscripts[id]]);
18645 break;
18646 }
18647 case 5: //eweapon
18648 {
18649 int32_t id = assignscript_dlg[25].d1;
18650 if(id < 0 || aseweaponscripts[id] == "<none>" || aseweaponscripts[id].at(0) == '-') break;
18651 target = &(scripts[aseweaponscripts[id]]);
18652 break;
18653 }
18654 case 6: //hero
18655 {
18656 int32_t id = assignscript_dlg[28].d1;
18657 if(id < 0 || asplayerscripts[id] == "<none>" || asplayerscripts[id].at(0) == '-') break;
18658 target = &(scripts[asplayerscripts[id]]);
18659 break;
18660 }
18661 case 7: //dmap
18662 {
18663 int32_t id = assignscript_dlg[34].d1;
18664 if(id < 0 || asdmapscripts[id] == "<none>" || asdmapscripts[id].at(0) == '-') break;
18665 target = &(scripts[asdmapscripts[id]]);
18666 break;
18667 }
18668 case 8: //screen
18669 {
18670 int32_t id = assignscript_dlg[31].d1;
18671 if(id < 0 || asscreenscripts[id] == "<none>" || asscreenscripts[id].at(0) == '-') break;
18672 target = &(scripts[asscreenscripts[id]]);
18673 break;
18674 }
18675 case 9: //itemsprite
18676 {
18677 int32_t id = assignscript_dlg[37].d1;
18678 if(id < 0 || asitemspritescripts[id] == "<none>" || asitemspritescripts[id].at(0) == '-') break;
18679 target = &(scripts[asitemspritescripts[id]]);
18680 break;
18681 }
18682 case 10: //combo
18683 {
18684 int32_t id = assignscript_dlg[40].d1;
18685 if(id < 0 || ascomboscripts[id] == "<none>" || ascomboscripts[id].at(0) == '-') break;
18686 target = &(scripts[ascomboscripts[id]]);
18687 break;
18688 }
18689 case 11: //generic
18690 {
18691 int32_t id = assignscript_dlg[46].d1;
18692 if(id < 0 || asgenericscripts[id] == "<none>" || asgenericscripts[id].at(0) == '-') break;
18693 target = &(scripts[asgenericscripts[id]]);
18694 break;
18695 }
18696 case 12: //subscreen
18697 {
18698 int32_t id = assignscript_dlg[49].d1;
18699 if(id < 0 || assubscreenscripts[id] == "<none>" || assubscreenscripts[id].at(0) == '-') break;
18700 target = &(scripts[assubscreenscripts[id]]);
18701 break;
18702 }
18703 }
18704 if(target)
18705 showScriptInfo(&target->meta);
18706 break;
18707 }
18708
18709 case 44:
18710 //Clear, clear slots of current type- after a confirmation.
18711 {
18712 doClearSlots(&slotflags);
18713 break;
18714 }
18715 }
18716 }
18717
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(assign_mode == 2) //Smart Assign
18718 {
18719 //For global/hero scripts, match slot names if unoccupied
18720 smart_slot_named(scripts, asglobalscripts, globalmap, global_slotnames, 1, NUMSCRIPTGLOBAL);
18721 smart_slot_named(scripts, asplayerscripts, playermap, player_slotnames, 0, NUMSCRIPTHERO-1);
18722 //For other scripts, assign all un-assigned scripts
18723 smart_slot_type(scripts, asffcscripts, ffcmap, NUMSCRIPTFFC-1);
18724 smart_slot_type(scripts, asitemscripts, itemmap, NUMSCRIPTITEM-1);
18725 smart_slot_type(scripts, asnpcscripts, npcmap, NUMSCRIPTGUYS-1);
18726 smart_slot_type(scripts, aslweaponscripts, lwpnmap, NUMSCRIPTWEAPONS-1);
18727 smart_slot_type(scripts, aseweaponscripts, ewpnmap, NUMSCRIPTWEAPONS-1);
18728 smart_slot_type(scripts, asscreenscripts, screenmap, NUMSCRIPTSCREEN-1);
18729 smart_slot_type(scripts, asdmapscripts, dmapmap, NUMSCRIPTSDMAP-1);
18730 smart_slot_type(scripts, asitemspritescripts, itemspritemap, NUMSCRIPTSITEMSPRITE-1);
18731 smart_slot_type(scripts, ascomboscripts, comboscriptmap, NUMSCRIPTSCOMBODATA-1);
18732 smart_slot_type(scripts, asgenericscripts, genericmap, NUMSCRIPTSGENERIC-1);
18733 smart_slot_type(scripts, assubscreenscripts, subscreenmap, NUMSCRIPTSSUBSCREEN-1);
18734 }
18735 auto_do_slots:
18736 6 doslots_log_output = (assignscript_dlg[13].flags == D_SELECTED);
18737 6 doslots_comment_output = (assignscript_dlg[51].flags == D_SELECTED);
18738 6 doslot_scripts = &scripts;
18739 //OK
18740 {
18741
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(doslots_log_output)
18742 {
18743 string outstr;
18744 write_script(zasm, outstr, doslots_comment_output, doslot_scripts);
18745 safe_al_trace(outstr);
18746 }
18747 6 auto start_assign_time = std::chrono::steady_clock::now();
18748 6 string zasm_str;
18749
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 write_script(zasm, zasm_str, false, nullptr);
18750
18751 6 std::vector<ffscript> zasm;
18752
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(parse_script_string(zasm, zasm_str, false))
18753 goto exit_do_slots;
18754
18755 6 zasm_scripts.clear();
18756
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 zasm_scripts.emplace_back(std::make_shared<zasm_script>(std::move(zasm)));
18757
18758
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(ffcmap, 1, ffscripts))
18759 goto exit_do_slots;
18760
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(globalmap, 0, globalscripts))
18761 goto exit_do_slots;
18762
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(itemmap, 1, itemscripts))
18763 goto exit_do_slots;
18764
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(npcmap, 1, guyscripts))
18765 goto exit_do_slots;
18766
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(lwpnmap, 1, lwpnscripts))
18767 goto exit_do_slots;
18768
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(ewpnmap, 1, ewpnscripts))
18769 goto exit_do_slots;
18770
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(playermap, 1, playerscripts))
18771 goto exit_do_slots;
18772
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(dmapmap, 1, dmapscripts))
18773 goto exit_do_slots;
18774
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(screenmap, 1, screenscripts))
18775 goto exit_do_slots;
18776
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(itemspritemap, 1, itemspritescripts))
18777 goto exit_do_slots;
18778
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(comboscriptmap, 1, comboscripts))
18779 goto exit_do_slots;
18780
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(genericmap, 1, genericscripts))
18781 goto exit_do_slots;
18782
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if(!handle_slot_map(subscreenmap, 1, subscreenscripts))
18783 goto exit_do_slots;
18784
18785 6 auto end_assign_time = std::chrono::steady_clock::now();
18786
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 int compile_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(end_assign_time - start_assign_time).count();
18787
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 al_trace("Assign Slots took %d ms\n", compile_time_ms);
18788 6 char buf[256] = {0};
18789 12 sprintf(buf, "ZScripts successfully loaded into script slots"
18790 6 "\nAssign Slots took %d ms", compile_time_ms);
18791
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 auto sfx_id = vbound(zc_get_config("Compiler","compile_finish_sample",20),0,255);
18792
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 auto sfx_vol = vbound(zc_get_config("Compiler","compile_audio_volume",100),0,255);
18793
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if ( sfx_id > 0 && sfx_vol > 0)
18794
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 sfx(sfx_id, 128, false, true, sfx_vol / 1.28_zf);
18795
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(!assign_mode)
18796 InfoDialog("Slots Assigned",buf).show();
18797
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 kill_sfx();
18798 6 retval = true;
18799 6 goto exit_do_slots;
18800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 }
18801 exit_do_slots:
18802 6 doslot_scripts = nullptr;
18803 6 popup_zqdialog_end();
18804 6 return retval;
18805 }
18806
18807 static char slottype_str_buf[32];
18808
18809 const char *slottype_list(int32_t index, int32_t *list_size)
18810 {
18811 if(index >= 0)
18812 {
18813 bound(index,0,num_types-1);
18814
18815 switch(index)
18816 {
18817 case type_ffc:
18818 strcpy(slottype_str_buf, "FFC");
18819 break;
18820 case type_global:
18821 strcpy(slottype_str_buf, "Global");
18822 break;
18823 case type_itemdata:
18824 strcpy(slottype_str_buf, "Item");
18825 break;
18826 case type_npc:
18827 strcpy(slottype_str_buf, "NPC");
18828 break;
18829 case type_lweapon:
18830 strcpy(slottype_str_buf, "LWeapon");
18831 break;
18832 case type_eweapon:
18833 strcpy(slottype_str_buf, "EWeapon");
18834 break;
18835 case type_hero:
18836 strcpy(slottype_str_buf, "Hero");
18837 break;
18838 case type_dmap:
18839 strcpy(slottype_str_buf, "DMap");
18840 break;
18841 case type_screen:
18842 strcpy(slottype_str_buf, "Screen");
18843 break;
18844 case type_itemsprite:
18845 strcpy(slottype_str_buf, "ItemSprite");
18846 break;
18847 case type_combo:
18848 strcpy(slottype_str_buf, "Combo");
18849 break;
18850 case type_generic:
18851 strcpy(slottype_str_buf, "Generic");
18852 break;
18853 case type_subscreen:
18854 strcpy(slottype_str_buf, "Subscreen");
18855 break;
18856 }
18857
18858 return slottype_str_buf;
18859 }
18860 *list_size = 11;
18861 return NULL;
18862 }
18863 12 static ListData slottype_sel_list(slottype_list, &font);
18864
18865 static DIALOG clearslots_dlg[] =
18866 {
18867 12 { jwin_win_proc, 0, 0, 200, 159, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Clear Slots", NULL, NULL },
18868 12 { jwin_button_proc, 35, 132, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Confirm", NULL, NULL },
18869 12 { jwin_button_proc, 104, 132, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
18870 12 { jwin_droplist_proc, 50, 28+16, 70, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, (void *) &slottype_sel_list, NULL, NULL },
18871 12 { jwin_radio_proc, 40, 34+00, 81, 9, vc(14), vc(1), 0, D_SELECTED, 0, 0, (void *) "Clear Script Type:", NULL, NULL },
18872 12 { jwin_radio_proc, 40, 34+32, 81, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "Clear Missing (--) Slots", NULL, NULL },
18873 12 { jwin_radio_proc, 40, 34+80, 81, 9, vc(14), vc(1), 0, 0, 0, 0, (void *) "Clear All", NULL, NULL },
18874 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
18875 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
18876 };
18877
18878 void doClearSlots(byte* flags)
18879 {
18880 //{ Setup
18881 clearslots_dlg[0].dp2=get_zc_font(font_lfont);
18882 clearslots_dlg[3].d1 = get_selected_tab((TABPANEL*)assignscript_dlg[1].dp); //Default to current tab's type
18883 clearslots_dlg[4].flags |= D_SELECTED;
18884 clearslots_dlg[5].flags &= ~D_SELECTED;
18885 clearslots_dlg[6].flags &= ~D_SELECTED;
18886 if(((*flags) & SLOTMSGFLAG_MISSING) == 0)
18887 clearslots_dlg[5].flags |= D_DISABLED;
18888 else
18889 clearslots_dlg[5].flags &= ~D_DISABLED;
18890 //}
18891
18892 large_dialog(clearslots_dlg);
18893
18894 if(do_zqdialog(clearslots_dlg,2)==1)
18895 {
18896 int32_t q = 3;
18897 while((clearslots_dlg[++q].flags & D_SELECTED) == 0);
18898 switch(q)
18899 {
18900 case 4: //Clear type
18901 {
18902 clearAllSlots(clearslots_dlg[3].d1);
18903 break;
18904 }
18905 case 5: //Clear Missing
18906 {
18907 for(int32_t q = 0; q <= 10; ++q)
18908 clearAllSlots(q,SLOTMSGFLAG_MISSING);
18909 break;
18910 }
18911 case 6: //Clear ALL
18912 {
18913 for(int32_t q = 0; q <= 10; ++q)
18914 clearAllSlots(q);
18915 break;
18916 }
18917 }
18918 }
18919 }
18920
18921 static DIALOG exportzasm_dlg[] =
18922 {
18923 12 { jwin_win_proc, 0, 0, 200, 159, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Export ZASM", NULL, NULL },
18924 12 { jwin_button_proc, 35, 132, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Confirm", NULL, NULL },
18925 12 { jwin_button_proc, 104, 132, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
18926 12 { jwin_droplist_proc, 50, 28+16, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, (void *) &slottype_sel_list, NULL, NULL },
18927 12 { jwin_droplist_proc, 50, 28+48, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
18928 12 { jwin_text_proc, 50, 28+8, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Type:", NULL, NULL },
18929 12 { jwin_text_proc, 50, 28+40, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Slot:", NULL, NULL },
18930 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
18931 };
18932
18933 static DIALOG importzasm_dlg[] =
18934 {
18935 12 { jwin_win_proc, 0, 0, 200, 159, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Import ZASM", NULL, NULL },
18936 12 { jwin_button_proc, 35, 132, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "Confirm", NULL, NULL },
18937 12 { jwin_button_proc, 104, 132, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
18938 12 { jwin_droplist_proc, 50, 28+16, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, D_EXIT, 0, 0, (void *) &slottype_sel_list, NULL, NULL },
18939 12 { jwin_droplist_proc, 50, 28+48, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 0, 0, NULL, NULL, NULL },
18940 // 5
18941 12 { jwin_text_proc, 50, 28+8, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Type:", NULL, NULL },
18942 12 { jwin_text_proc, 50, 28+40, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Slot:", NULL, NULL },
18943 12 { jwin_text_proc, 50, 28+72, 16, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Script Name:", NULL, NULL },
18944 12 { jwin_edit_proc, 50, 28+80, 100, 16, jwin_pal[jcTEXTFG], jwin_pal[jcTEXTBG], 0, 0, 19, 0, NULL, NULL, NULL },
18945
18946 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
18947 };
18948
18949 1 void center_zscript_dialogs()
18950 {
18951 1 jwin_center_dialog(exportzasm_dlg);
18952 1 jwin_center_dialog(importzasm_dlg);
18953 1 jwin_center_dialog(clearslots_dlg);
18954 1 }
18955
18956 // array of voices, one for each sfx sample in the data file
18957 // 0+ = voice #
18958 // -1 = voice not allocated
18959 int32_t sfx_voice[WAV_COUNT];
18960
18961 void Z_init_sound()
18962 {
18963 for(int32_t i=0; i<WAV_COUNT; i++)
18964 sfx_voice[i]=-1;
18965
18966 // master_volume(digi_volume,midi_volume);
18967 }
18968
18969 // returns number of voices currently allocated
18970 int32_t sfx_count()
18971 {
18972 int32_t c=0;
18973
18974 for(int32_t i=0; i<WAV_COUNT; i++)
18975 if(sfx_voice[i]!=-1)
18976 ++c;
18977
18978 return c;
18979 }
18980
18981 // clean up finished samples
18982 void sfx_cleanup()
18983 {
18984 for(int32_t i=0; i<WAV_COUNT; i++)
18985 if(sfx_voice[i]!=-1 && voice_get_position(sfx_voice[i])<0)
18986 {
18987 deallocate_voice(sfx_voice[i]);
18988 sfx_voice[i]=-1;
18989 }
18990 }
18991
18992 bool sfx_templist = false;
18993 SAMPLE templist[WAV_COUNT];
18994 12 SAMPLE* sfx_get_sample(int32_t index)
18995 {
18996 // check index
18997
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if (index<=0 || index>=WAV_COUNT)
18998 return nullptr;
18999
19000
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (sfx_templist)
19001 {
19002 if (templist[index].data)
19003 return &templist[index];
19004 else return nullptr;
19005 }
19006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 else if (sfxdat)
19007 {
19008 if (index<Z35)
19009 {
19010 return (SAMPLE*)sfxdata[index].dat;
19011 }
19012 else
19013 {
19014 return (SAMPLE*)sfxdata[Z35].dat;
19015 }
19016 }
19017 else
19018 {
19019 12 return &customsfxdata[index];
19020 }
19021
19022 return nullptr;
19023 12 }
19024
19025 12 bool sfx_init(int32_t index)
19026 {
19027 // check index
19028
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(index<1 || index>=WAV_COUNT)
19029 return false;
19030
19031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if(sfx_voice[index]==-1)
19032 {
19033 12 SAMPLE* sample = sfx_get_sample(index);
19034
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (!sample)
19035 return false;
19036
19037 12 sfx_voice[index] = allocate_voice(sample);
19038 12 }
19039
19040 12 return sfx_voice[index] != -1;
19041 12 }
19042
19043 // plays an sfx sample
19044 12 void sfx(int32_t index,int32_t pan,bool loop,bool restart,zfix vol_perc,int32_t freq)
19045 {
19046
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(!sfx_init(index))
19047 return;
19048
19049 12 voice_set_playmode(sfx_voice[index],loop?PLAYMODE_LOOP:PLAYMODE_PLAY);
19050 12 voice_set_pan(sfx_voice[index],pan);
19051
19052 12 int32_t pos = voice_get_position(sfx_voice[index]);
19053
19054 12 int temp_volume = (128 * (vol_perc / 100)).getFloor();
19055
19056
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(restart) voice_set_position(sfx_voice[index],0);
19057 12 voice_set_volume(sfx_voice[index], temp_volume);
19058
19059
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(pos<=0)
19060 12 voice_start(sfx_voice[index]);
19061 12 }
19062
19063 // start it (in loop mode) if it's not already playing,
19064 // otherwise just leave it in its current position
19065 void cont_sfx(int32_t index)
19066 {
19067 if(!sfx_init(index))
19068 return;
19069
19070 if(voice_get_position(sfx_voice[index])<=0)
19071 {
19072 voice_set_position(sfx_voice[index],0);
19073 voice_set_playmode(sfx_voice[index],PLAYMODE_LOOP);
19074 voice_start(sfx_voice[index]);
19075 }
19076 }
19077
19078 // adjust parameters while playing
19079 void adjust_sfx(int32_t index,int32_t pan,bool loop)
19080 {
19081 if(index<0 || index>=WAV_COUNT || sfx_voice[index]==-1)
19082 return;
19083
19084 voice_set_playmode(sfx_voice[index],loop?PLAYMODE_LOOP:PLAYMODE_PLAY);
19085 voice_set_pan(sfx_voice[index],pan);
19086 }
19087
19088 // pauses a voice
19089 void pause_sfx(int32_t index)
19090 {
19091 if(index>=0 && index<WAV_COUNT && sfx_voice[index]!=-1)
19092 voice_stop(sfx_voice[index]);
19093 }
19094
19095 // resumes a voice
19096 void resume_sfx(int32_t index)
19097 {
19098 if(index>=0 && index<WAV_COUNT && sfx_voice[index]!=-1)
19099 voice_start(sfx_voice[index]);
19100 }
19101
19102 // pauses all active voices
19103 void pause_all_sfx()
19104 {
19105 for(int32_t i=0; i<WAV_COUNT; i++)
19106 if(sfx_voice[i]!=-1)
19107 voice_stop(sfx_voice[i]);
19108 }
19109
19110 // resumes all paused voices
19111 void resume_all_sfx()
19112 {
19113 for(int32_t i=0; i<WAV_COUNT; i++)
19114 if(sfx_voice[i]!=-1)
19115 voice_start(sfx_voice[i]);
19116 }
19117
19118 // stops an sfx and deallocates the voice
19119 void stop_sfx(int32_t index)
19120 {
19121 if(index<0 || index>=WAV_COUNT)
19122 return;
19123
19124 if(sfx_voice[index]!=-1)
19125 {
19126 deallocate_voice(sfx_voice[index]);
19127 sfx_voice[index]=-1;
19128 }
19129 }
19130
19131 18 void kill_sfx()
19132 {
19133
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 18 times.
4626 for(int32_t i=0; i<WAV_COUNT; i++)
19134
2/2
✓ Branch 0 taken 3060 times.
✓ Branch 1 taken 1548 times.
6156 if(sfx_voice[i]!=-1)
19135 {
19136 1548 deallocate_voice(sfx_voice[i]);
19137 1548 sfx_voice[i]=-1;
19138 1548 }
19139 18 }
19140
19141 int32_t pan(int32_t x)
19142 {
19143 return 128;
19144 /*switch(pan_style)
19145 {
19146 case 0: return 128;
19147 case 1: return vbound((x>>1)+68,0,255);
19148 case 2: return vbound(((x*3)>>2)+36,0,255);
19149 }
19150 return vbound(x,0,255);*/
19151 }
19152
19153
19154 void change_sfx(SAMPLE *sfx1, SAMPLE *sfx2)
19155 {
19156 sfx1->bits = sfx2->bits;
19157 sfx1->stereo = sfx2->stereo;
19158 sfx1->freq = sfx2->freq;
19159 sfx1->priority = sfx2->priority;
19160 sfx1->len = sfx2->len;
19161 sfx1->loop_start = sfx2->loop_start;
19162 sfx1->loop_end = sfx2->loop_end;
19163 sfx1->param = sfx2->param;
19164
19165 if(sfx1->data != NULL)
19166 {
19167 free(sfx1->data);
19168 }
19169
19170 if(sfx2->data == NULL)
19171 sfx1->data = NULL;
19172 else
19173 {
19174 // When quests are saved and loaded, data is written in words.
19175 // If the last byte is dropped, it'll cause the sound to end with
19176 // a click. It could simply be extended and padded with 0, but
19177 // that causes compatibility issues... So we'll cut off
19178 // the last byte and decrease the length.
19179
19180 int32_t len = (sfx1->bits==8?1:2)*(sfx1->stereo == 0 ? 1 : 2)*sfx1->len;
19181
19182 while(len%sizeof(word))
19183 {
19184 // sizeof(word) should be 2, so this doesn't really need
19185 // to be a loop, but what the heck.
19186 sfx1->len--;
19187 len = (sfx1->bits==8?1:2)*(sfx1->stereo == 0 ? 1 : 2)*sfx1->len;
19188 }
19189
19190 sfx1->data = malloc(len);
19191 memcpy(sfx1->data, sfx2->data, len);
19192 }
19193 }
19194
19195 int32_t onSelectSFX()
19196 {
19197 SFXListerDialog(0).show();
19198 refresh(rMAP+rCOMBOS);
19199 return D_O_K;
19200 }
19201
19202 bool saveWAV(int32_t slot, const char *filename)
19203 {
19204 if (slot < 1 || slot >= 511 )
19205 return false;
19206
19207 if (customsfxdata[slot].data == NULL)
19208 return false;
19209
19210 std::ofstream ofs(filename, std::ios::binary);
19211 if (!ofs)
19212 return false;
19213 ofs.write("RIFF",4);
19214 uint32_t samplerate = customsfxdata[slot].freq;
19215 uint16_t channels = customsfxdata[slot].stereo ? 2 : 1;
19216 uint32_t datalen = customsfxdata[slot].len*channels*customsfxdata[slot].bits / 8;
19217 uint32_t size = 36 + datalen;
19218 ofs.write((char *)&size, 4);
19219 ofs.write("WAVE", 4);
19220 ofs.write("fmt ", 4);
19221 uint32_t fmtlen = 16;
19222 ofs.write((char *)&fmtlen, 4);
19223 uint16_t type = 1;
19224 ofs.write((char *)&type, 2);
19225 ofs.write((char *)&channels, 2);
19226 ofs.write((char *)&samplerate, 4);
19227 uint32_t bytespersec = samplerate*channels*customsfxdata[slot].bits / 8;
19228 ofs.write((char *)&bytespersec, 4);
19229 uint16_t blockalign = channels*customsfxdata[slot].bits / 8;
19230 ofs.write((char *)&blockalign, 2);
19231 uint16_t bitspersample = customsfxdata[slot].bits;
19232 ofs.write((char *)&bitspersample, 2);
19233 ofs.write("data", 4);
19234 ofs.write((char *)&datalen, 4);
19235 if (bitspersample == 8)
19236 {
19237 for (int32_t i = 0; i < (int32_t)customsfxdata[slot].len*channels; i++)
19238 {
19239 char data = ((char *)customsfxdata[slot].data)[i];
19240 data ^= 0x80;
19241 ofs.write(&data, 1);
19242 }
19243 }
19244 else if (bitspersample == 16)
19245 {
19246 for (int32_t i = 0; i < (int32_t)customsfxdata[slot].len*channels; i++)
19247 {
19248 uint16_t data = ((uint16_t *)customsfxdata[slot].data)[i];
19249 data ^= 0x8000;
19250 ofs.write((char *)&data, 2);
19251 }
19252 }
19253 else
19254 return false;
19255 return !!ofs;
19256 }
19257
19258 int32_t onMapStyles()
19259 {
19260 call_mapstyles_dialog();
19261 return D_O_K;
19262 }
19263
19264 int32_t d_misccolors_old_proc(int32_t msg,DIALOG *d,int32_t c)
19265 {
19266 //these are here to bypass compiler warnings about unused arguments
19267 c=c;
19268
19269 if(msg==MSG_DRAW)
19270 {
19271 textout_ex(screen,font,"0123456789ABCDEF",d->x+8,d->y,d->fg,d->bg);
19272 textout_ex(screen,font,"0",d->x,d->y+8,d->fg,d->bg);
19273 textout_ex(screen,font,"1",d->x,d->y+16,d->fg,d->bg);
19274 textout_ex(screen,font,"5",d->x,d->y+24,d->fg,d->bg);
19275
19276 for(int32_t i=0; i<32; i++)
19277 {
19278 int32_t px2 = d->x+((i&15)<<3)+8;
19279 int32_t py2 = d->y+((i>>4)<<3)+8;
19280 rectfill(screen,px2,py2,px2+7,py2+7,i);
19281 }
19282
19283 for(int32_t i=0; i<16; i++)
19284 {
19285 int32_t px2 = d->x+(i<<3)+8;
19286 rectfill(screen,px2,d->y+24,px2+7,d->y+31,i+80);
19287 }
19288 }
19289
19290 return D_O_K;
19291 }
19292
19293 int32_t hexclicked=-1;
19294
19295 int32_t d_misccolors_hexedit_proc(int32_t msg,DIALOG *d,int32_t c)
19296 {
19297 switch(msg)
19298 {
19299 case MSG_GOTFOCUS:
19300 hexclicked=((int32_t)(size_t)(d->dp3))+20;
19301 break;
19302
19303 case MSG_LOSTFOCUS:
19304 hexclicked=-1;
19305 break;
19306 }
19307
19308 return d_hexedit_proc(msg,d,c);
19309 }
19310
19311
19312 int32_t d_misccolors_proc(int32_t msg,DIALOG *d,int32_t c);
19313
19314 static int32_t misccolor1_list[] =
19315 {
19316 // dialog control number
19317 4, 5, 6, 7, 8, 20, 21, 22, 23, 24, 36, 37, 38, 39, 40, -1
19318 };
19319
19320 static int32_t misccolor2_list[] =
19321 {
19322 // dialog control number
19323 9, 10, 11, 12, 13, 25, 26, 27, 28, 29, 41, 42, 43, 44, 45, -1
19324 };
19325
19326 static int32_t misccolor3_list[] =
19327 {
19328 // dialog control number
19329 14, 15, 16, 17, 18, 30, 31, 32, 33, 34, 46, 47, 48, 49, 50, -1
19330 };
19331
19332 static int32_t misccolor4_list[] =
19333 {
19334 19, 35, 51, 54, 55, 56, -1
19335 };
19336
19337 static TABPANEL misccolor_tabs[] =
19338 {
19339 // (text)
19340 { (char *)"1", D_SELECTED, misccolor1_list, 0, NULL },
19341 { (char *)"2", 0, misccolor2_list, 0, NULL },
19342 { (char *)"3", 0, misccolor3_list, 0, NULL },
19343 { (char *)"4", 0, misccolor4_list, 0, NULL },
19344 { NULL, 0, NULL, 0, NULL }
19345 };
19346
19347 int32_t d_misccolors_tab_proc(int32_t msg,DIALOG *d,int32_t c);
19348
19349 static DIALOG misccolors_dlg[] =
19350 {
19351 // (dialog proc) (x) (y) (w) (h) (fg) (bg) (key) (flags) (d1) (d2) (dp)
19352 12 { jwin_win_proc, 2, 21, 316, 197-23, vc(14), vc(1), 0, D_EXIT, 0, 0, (void *) "Misc Colors", NULL, NULL },
19353 // { jwin_frame_proc, 98-84+1+2, 52+8-6+4, 132, 100, vc(15), vc(1), 0, 0, FR_DEEP, 0, NULL, NULL, NULL },
19354 12 { d_timer_proc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL },
19355 12 { d_misccolors_proc, 92-84+1+2, 44+8-6+4, 128+8, 96+8, vc(9), vc(1), 0, 0, 0, 0, NULL, NULL, NULL },
19356 //3
19357 12 { d_misccolors_tab_proc, 150+14-2+10-15, 60-14, 150-10+15, 144-20-10, jwin_pal[jcBOXFG], jwin_pal[jcBOX], 0, 0, 0, 0, (void *) misccolor_tabs, NULL, (void *)misccolors_dlg },
19358 //4
19359 12 { jwin_text_proc, 215-25-12-15, 76-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Text:", NULL, NULL },
19360 12 { jwin_text_proc, 215-25-12-15, 94-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Caption:", NULL, NULL },
19361 12 { jwin_text_proc, 215-25-12-15, 112-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Overworld Minmap:", NULL, NULL },
19362 12 { jwin_text_proc, 215-25-12-15, 130-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Minimap Background:", NULL, NULL },
19363 12 { jwin_text_proc, 215-25-12-15, 148-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Minimap Foreground 1:", NULL, NULL },
19364 12 { jwin_text_proc, 215-25-12-15, 76-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Minimap Foreground 2:", NULL, NULL },
19365 12 { jwin_text_proc, 215-25-12-15, 94-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "BS Minimap Dark:", NULL, NULL },
19366 12 { jwin_text_proc, 215-25-12-15, 112-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "BS Minimap Goal:", NULL, NULL },
19367 12 { jwin_text_proc, 215-25-12-15, 130-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Compass Mark (Light):", NULL, NULL },
19368 12 { jwin_text_proc, 215-25-12-15, 148-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Compass Mark (Dark):", NULL, NULL },
19369 12 { jwin_text_proc, 215-25-12-15, 76-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Subscreen Background:", NULL, NULL },
19370 12 { jwin_text_proc, 215-25-12-15, 94-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Subscreen Shadow:", NULL, NULL },
19371 12 { jwin_text_proc, 215-25-12-15, 112-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Triforce Frame:", NULL, NULL },
19372 12 { jwin_text_proc, 215-25-12-15, 130-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Big Map Background:", NULL, NULL },
19373 12 { jwin_text_proc, 215-25-12-15, 148-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Big Map Foreground:", NULL, NULL },
19374 12 { jwin_text_proc, 215-25-12-15, 76-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Hero's Position:", NULL, NULL },
19375
19376 //20
19377 12 { d_misccolors_hexedit_proc, 294-25+14+2, 76-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)0, },
19378 12 { d_misccolors_hexedit_proc, 294-25+14+2, 94-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)1, },
19379 12 { d_misccolors_hexedit_proc, 294-25+14+2, 112-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)2, },
19380 12 { d_misccolors_hexedit_proc, 294-25+14+2, 130-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)3, },
19381 12 { d_misccolors_hexedit_proc, 294-25+14+2, 148-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)4, },
19382 12 { d_misccolors_hexedit_proc, 294-25+14+2, 76-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)5, },
19383 12 { d_misccolors_hexedit_proc, 294-25+14+2, 94-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)6, },
19384 12 { d_misccolors_hexedit_proc, 294-25+14+2, 112-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)7, },
19385 12 { d_misccolors_hexedit_proc, 294-25+14+2, 130-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)8, },
19386 12 { d_misccolors_hexedit_proc, 294-25+14+2, 148-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)9, },
19387 12 { d_misccolors_hexedit_proc, 294-25+14+2, 76-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)10, },
19388 12 { d_misccolors_hexedit_proc, 294-25+14+2, 94-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)11, },
19389 12 { d_misccolors_hexedit_proc, 294-25+14+2, 112-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)12, },
19390 12 { d_misccolors_hexedit_proc, 294-25+14+2, 130-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)13, },
19391 12 { d_misccolors_hexedit_proc, 294-25+14+2, 148-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)14, },
19392 12 { d_misccolors_hexedit_proc, 294-25+14+2, 76-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)15, },
19393
19394 //36
19395 12 { jwin_text_proc, 283-25+14+2, 76-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19396 12 { jwin_text_proc, 283-25+14+2, 94-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19397 12 { jwin_text_proc, 283-25+14+2, 112-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19398 12 { jwin_text_proc, 283-25+14+2, 130-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19399 12 { jwin_text_proc, 283-25+14+2, 148-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19400 12 { jwin_text_proc, 283-25+14+2, 76-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19401 12 { jwin_text_proc, 283-25+14+2, 94-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19402 12 { jwin_text_proc, 283-25+14+2, 112-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19403 12 { jwin_text_proc, 283-25+14+2, 130-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19404 12 { jwin_text_proc, 283-25+14+2, 148-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19405 12 { jwin_text_proc, 283-25+14+2, 76-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19406 12 { jwin_text_proc, 283-25+14+2, 94-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19407 12 { jwin_text_proc, 283-25+14+2, 112-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19408 12 { jwin_text_proc, 283-25+14+2, 130-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19409 12 { jwin_text_proc, 283-25+14+2, 148-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19410 12 { jwin_text_proc, 283-25+14+2, 76-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19411
19412 //52
19413 12 { jwin_button_proc, 90, 190-20, 61, 21, vc(14), vc(1), 13, D_EXIT, 0, 0, (void *) "OK", NULL, NULL },
19414 12 { jwin_button_proc, 170, 190-20, 61, 21, vc(14), vc(1), 27, D_EXIT, 0, 0, (void *) "Cancel", NULL, NULL },
19415 12 { jwin_text_proc, 215-25-12-15, 94-4, 0, 8, vc(11), vc(1), 0, 0, 0, 0, (void *) "Message Text:", NULL, NULL },
19416 12 { d_misccolors_hexedit_proc, 294-25+14+2, 94-8, 21, 16, vc(11), vc(1), 0, 0, 2, 0, NULL, NULL, (void *)35, },
19417 12 { jwin_text_proc, 283-25+14+2, 94-4, 0, 8, vc(11), vc(1), 0, 0, 2, 0, (void *) "0x", NULL, NULL },
19418 12 { NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
19419 };
19420
19421 int32_t d_misccolors_tab_proc(int32_t msg,DIALOG *d,int32_t c)
19422 {
19423
19424 switch(msg)
19425 {
19426 case MSG_WANTFOCUS:
19427 return D_WANTFOCUS;
19428 break;
19429 }
19430
19431 return jwin_tab_proc(msg,d,c);
19432 }
19433
19434
19435 int32_t d_misccolors_proc(int32_t msg,DIALOG *d,int32_t c)
19436 {
19437 //these are here to bypass compiler warnings about unused arguments
19438 c=c;
19439 int32_t mul=12;
19440
19441 switch(msg)
19442 {
19443 case MSG_CLICK:
19444 if(hexclicked!=-1)
19445 {
19446 int32_t color_col=vbound(((gui_mouse_x()-d->x-8)/mul),0,15);
19447 int32_t color_row=vbound(((gui_mouse_y()-d->y-10)/mul),0,11);
19448 sprintf((char*)misccolors_dlg[hexclicked].dp,"%X%X",color_row,color_col);
19449 object_message(misccolors_dlg+hexclicked,MSG_DRAW,0);
19450 }
19451
19452 break;
19453
19454 case MSG_DRAW:
19455 for(int32_t i=0; i<10; i++)
19456 {
19457 textprintf_centre_ex(screen,font,d->x+8+4+(i*mul),d->y,jwin_pal[jcBOXFG],jwin_pal[jcBOX], "%d", i);
19458 }
19459
19460 for(int32_t i=0; i<6; i++)
19461 {
19462 textprintf_centre_ex(screen,font,d->x+8+4+((10+i)*mul),d->y,jwin_pal[jcBOXFG],jwin_pal[jcBOX], "%c", i+'A');
19463 }
19464
19465 for(int32_t i=0; i<10; i++)
19466 {
19467 textprintf_right_ex(screen,font,d->x+6,d->y+(i*mul)+10,jwin_pal[jcBOXFG],jwin_pal[jcBOX], "%d", i);
19468 }
19469
19470 for(int32_t i=0; i<2; i++)
19471 {
19472 textprintf_right_ex(screen,font,d->x+6,d->y+((i+10)*mul)+10,jwin_pal[jcBOXFG],jwin_pal[jcBOX], "%c", i+'A');
19473 }
19474
19475 jwin_draw_frame(screen,d->x+6,d->y+8,int32_t(132*1.5)-2,int32_t(100*1.5)-2,FR_DEEP);
19476
19477 for(int32_t i=0; i<192; i++)
19478 {
19479 int32_t px2 = d->x+int32_t(((i&15)<<3)*1.5)+8;
19480 int32_t py2 = d->y+int32_t(((i>>4)<<3)*1.5)+8+2;
19481 rectfill(screen,px2,py2,px2+(mul-1),py2+(mul-1),i);
19482 }
19483
19484 break;
19485 }
19486
19487 return D_O_K;
19488 }
19489
19490
19491 int32_t onMiscColors()
19492 {
19493 char buf[17][3];
19494 byte *si = &(QMisc.colors.text);
19495 misccolors_dlg[0].dp2=get_zc_font(font_lfont);
19496
19497 for(int32_t i=0; i<16; i++)
19498 {
19499 sprintf(buf[i],"%02X",*(si++));
19500 sprintf(buf[16], "%02X", QMisc.colors.msgtext);
19501 misccolors_dlg[i+20].dp = buf[i];
19502 misccolors_dlg[55].dp = buf[16];
19503 }
19504
19505 large_dialog(misccolors_dlg);
19506
19507 if(do_zqdialog(misccolors_dlg,0)==52)
19508 {
19509 mark_save_dirty();
19510 si = &(QMisc.colors.text);
19511
19512 for(int32_t i=0; i<16; i++)
19513 {
19514 *si = zc_xtoi(buf[i]);
19515 ++si;
19516 }
19517
19518 QMisc.colors.msgtext = zc_xtoi(buf[16]);
19519 }
19520
19521 return D_O_K;
19522 }
19523
19524 // **** Palette cycling ****
19525
19526 static int32_t palclk[3];
19527 static int32_t palpos[3];
19528
19529 22 void reset_pal_cycling()
19530 {
19531
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 22 times.
88 for(int32_t i=0; i<3; i++)
19532 66 palclk[i]=palpos[i]=0;
19533 22 }
19534
19535 void cycle_palette()
19536 {
19537 if(!get_qr(qr_FADE))
19538 return;
19539
19540 int32_t level = Map.CurrScr()->color;
19541 bool refreshpal = false;
19542
19543 for(int32_t i=0; i<3; i++)
19544 {
19545 palcycle c = QMisc.cycles[level][i];
19546
19547 if(c.count&0xF0)
19548 {
19549 if(++palclk[i] >= c.speed)
19550 {
19551 palclk[i]=0;
19552
19553 if(++palpos[i] >= (c.count>>4))
19554 palpos[i]=0;
19555
19556 byte *si = colordata + CSET(level*pdLEVEL+poFADE1+1+palpos[i])*3;
19557
19558 si += (c.first&15)*3;
19559
19560 for(int32_t col=c.first&15; col<=(c.count&15); col++)
19561 {
19562 RAMpal[CSET(c.first>>4)+col] = _RGB(si);
19563 si+=3;
19564 }
19565
19566 refreshpal = true;
19567 }
19568 }
19569 }
19570
19571 if(refreshpal)
19572 {
19573 rebuild_trans_table();
19574 zc_set_palette_range(RAMpal,0,192,false);
19575 }
19576 }
19577
19578
19579 static void doHelp()
19580 {
19581 do_box_edit(helpstr, "ZQuest Help", true, true);
19582 }
19583
19584 int32_t onHelp()
19585 {
19586 restore_mouse();
19587 doHelp();
19588 return D_O_K;
19589 }
19590
19591 void doZstringshelp()
19592 {
19593 do_box_edit(zstringshelpstr, "ZStrings Help", true, true);
19594 }
19595
19596 int32_t onZstringshelp()
19597 {
19598 restore_mouse();
19599 doZstringshelp();
19600 return D_O_K;
19601 }
19602
19603 void call_layer_dialog(int map, int scr);
19604 int32_t onLayers()
19605 {
19606 call_layer_dialog(Map.getCurrMap(), Map.getCurrScr());
19607 if (CurrentLayer > 0 && Map.CurrScr()->layermap[CurrentLayer-1] == 0)
19608 CurrentLayer = 0;
19609 return D_O_K;
19610 }
19611
19612 void fps_callback()
19613 {
19614 lastfps=framecnt;
19615 framecnt=0;
19616 }
19617
19618 END_OF_FUNCTION(fps_callback)
19619
19620 //uint32_t col_diff[3*128];
19621 /*
19622 void bestfit_init(void)
19623 {
19624 int32_t i;
19625
19626 for (i=1; i<64; i++)
19627
19628 {
19629 int32_t k = i * i;
19630 col_diff[0 +i] = col_diff[0 +128-i] = k * (59 * 59);
19631 col_diff[128+i] = col_diff[128+128-i] = k * (30 * 30);
19632 col_diff[256+i] = col_diff[256+128-i] = k * (11 * 11);
19633 }
19634 }
19635 */
19636 void create_rgb_table2(RGB_MAP *table, AL_CONST PALETTE pal_8bit, void (*callback)(int32_t pos))
19637 {
19638 #define UNUSED 65535
19639 #define LAST 65532
19640
19641 // Allegro has been modified to use an 8 bit palette, but this method and RGB_MAP still use 6 bit.
19642 PALETTE pal;
19643 for (int i = 0; i < 256; i++)
19644 {
19645 pal[i] = pal_8bit[i];
19646 pal[i].r /= 4;
19647 pal[i].g /= 4;
19648 pal[i].b /= 4;
19649 }
19650
19651 /* macro add adds to single linked list */
19652 #define add(i) (next[(i)] == UNUSED ? (next[(i)] = LAST, \
19653 (first != LAST ? (next[last] = (i)) : (first = (i))), \
19654 (last = (i))) : 0)
19655
19656 /* same but w/o checking for first element */
19657 #define add1(i) (next[(i)] == UNUSED ? (next[(i)] = LAST, \
19658 next[last] = (i), \
19659 (last = (i))) : 0)
19660 /* calculates distance between two colors */
19661 #define dist(a1, a2, a3, b1, b2, b3) \
19662 (col_diff[ ((a2) - (b2)) & 0x7F] + \
19663 (col_diff + 128)[((a1) - (b1)) & 0x7F] + \
19664 (col_diff + 256)[((a3) - (b3)) & 0x7F])
19665
19666 /* converts r,g,b to position in array and back */
19667 #define pos(r, g, b) \
19668 (((r) / 2) * 32 * 32 + ((g) / 2) * 32 + ((b) / 2))
19669
19670 #define depos(pal, r, g, b) \
19671 ((b) = ((pal) & 31) * 2, \
19672 (g) = (((pal) >> 5) & 31) * 2, \
19673 (r) = (((pal) >> 10) & 31) * 2)
19674
19675 /* is current color better than pal1? */
19676 #define better(r1, g1, b1, pal1) \
19677 (((int32_t)dist((r1), (g1), (b1), \
19678 (pal1).r, (pal1).g, (pal1).b)) > (int32_t)dist2)
19679
19680 /* checking of position */
19681 #define dopos(rp, gp, bp, ts) \
19682 if ((rp > -1 || r > 0) && (rp < 1 || r < 61) && \
19683 (gp > -1 || g > 0) && (gp < 1 || g < 61) && \
19684 (bp > -1 || b > 0) && (bp < 1 || b < 61)) \
19685 { \
19686 i = first + rp * 32 * 32 + gp * 32 + bp; \
19687 if (!data[i]) \
19688 { \
19689 data[i] = val; \
19690 add1(i); \
19691 } \
19692 else if ((ts) && (data[i] != val)) \
19693 { \
19694 dist2 = (rp ? (col_diff+128)[(r+2*rp-pal[val].r) & 0x7F] : r2) + \
19695 (gp ? (col_diff )[(g+2*gp-pal[val].g) & 0x7F] : g2) + \
19696 (bp ? (col_diff+256)[(b+2*bp-pal[val].b) & 0x7F] : b2); \
19697 if (better((r+2*rp), (g+2*gp), (b+2*bp), pal[data[i]])) \
19698 { \
19699 data[i] = val; \
19700 add1(i); \
19701 } \
19702 } \
19703 }
19704
19705 int32_t i, curr, r, g, b, val, dist2;
19706 uint32_t r2, g2, b2;
19707 uint16_t next[32*32*32];
19708 uint8_t *data;
19709 int32_t first = LAST;
19710 int32_t last = LAST;
19711 int32_t count = 0;
19712 int32_t cbcount = 0;
19713
19714 #define AVERAGE_COUNT 18000
19715
19716 if(col_diff[1] == 0)
19717 bestfit_init();
19718
19719 memset(next, 255, sizeof(next));
19720 memset(table->data, 0, sizeof(char)*32*32*32);
19721
19722
19723 data = (uint8_t *)table->data;
19724
19725 /* add starting seeds for floodfill */
19726 for(i=1; i<PAL_SIZE; i++)
19727 {
19728 curr = pos(pal[i].r, pal[i].g, pal[i].b);
19729
19730 if(next[curr] == UNUSED)
19731 {
19732 data[curr] = i;
19733 add(curr);
19734 }
19735 }
19736
19737 /* main floodfill: two versions of loop for faster growing in blue axis */
19738 // while (first != LAST) {
19739 while(first < LAST)
19740 {
19741 depos(first, r, g, b);
19742
19743 /* calculate distance of current color */
19744 val = data[first];
19745 r2 = (col_diff+128)[((pal[val].r)-(r)) & 0x7F];
19746 g2 = (col_diff)[((pal[val].g)-(g)) & 0x7F];
19747 b2 = (col_diff+256)[((pal[val].b)-(b)) & 0x7F];
19748
19749 /* try to grow to all directions */
19750 #ifdef _MSC_VER
19751 #pragma warning(disable:4127)
19752 #endif
19753 dopos(0, 0, 1, 1);
19754 dopos(0, 0,-1, 1);
19755 dopos(1, 0, 0, 1);
19756 dopos(-1, 0, 0, 1);
19757 dopos(0, 1, 0, 1);
19758 dopos(0,-1, 0, 1);
19759 #ifdef _MSC_VER
19760 #pragma warning(default:4127)
19761 #endif
19762
19763 /* faster growing of blue direction */
19764 if((b > 0) && (data[first-1] == val))
19765 {
19766 b -= 2;
19767 first--;
19768 b2 = (col_diff+256)[((pal[val].b)-(b)) & 0x7F];
19769
19770 #ifdef _MSC_VER
19771 #pragma warning(disable:4127)
19772 #endif
19773 dopos(-1, 0, 0, 0);
19774 dopos(1, 0, 0, 0);
19775 dopos(0,-1, 0, 0);
19776 dopos(0, 1, 0, 0);
19777 #ifdef _MSC_VER
19778 #pragma warning(default:4127)
19779 #endif
19780
19781 first++;
19782 }
19783
19784 /* get next from list */
19785 i = first;
19786 first = next[first];
19787 next[i] = UNUSED;
19788
19789 /* second version of loop */
19790 // if (first != LAST) {
19791 if(first < LAST)
19792 {
19793
19794 depos(first, r, g, b);
19795
19796 val = data[first];
19797 r2 = (col_diff+128)[((pal[val].r)-(r)) & 0x7F];
19798 g2 = (col_diff)[((pal[val].g)-(g)) & 0x7F];
19799 b2 = (col_diff+256)[((pal[val].b)-(b)) & 0x7F];
19800
19801 #ifdef _MSC_VER
19802 #pragma warning(disable:4127)
19803 #endif
19804 dopos(0, 0, 1, 1);
19805 dopos(0, 0,-1, 1);
19806 dopos(1, 0, 0, 1);
19807 dopos(-1, 0, 0, 1);
19808 dopos(0, 1, 0, 1);
19809 dopos(0,-1, 0, 1);
19810 #ifdef _MSC_VER
19811 #pragma warning(default:4127)
19812 #endif
19813
19814 if((b < 61) && (data[first + 1] == val))
19815 {
19816 b += 2;
19817 first++;
19818 b2 = (col_diff+256)[((pal[val].b)-(b)) & 0x7f];
19819 #ifdef _MSC_VER
19820 #pragma warning(disable:4127)
19821 #endif
19822 dopos(-1, 0, 0, 0);
19823 dopos(1, 0, 0, 0);
19824 dopos(0,-1, 0, 0);
19825 dopos(0, 1, 0, 0);
19826 #ifdef _MSC_VER
19827 #pragma warning(default:4127)
19828 #endif
19829
19830 first--;
19831 }
19832
19833 i = first;
19834 first = next[first];
19835 next[i] = UNUSED;
19836 }
19837
19838 count++;
19839
19840 if(count == (cbcount+1)*AVERAGE_COUNT/256)
19841 {
19842 if(cbcount < 256)
19843 {
19844 if(callback)
19845 callback(cbcount);
19846
19847 cbcount++;
19848 }
19849 }
19850
19851 }
19852
19853 /* only the transparent (pink) color can be mapped to index 0 */
19854 if((pal[0].r == 63) && (pal[0].g == 0) && (pal[0].b == 63))
19855 table->data[31][0][31] = 0;
19856
19857 if(callback)
19858 while(cbcount < 256)
19859 callback(cbcount++);
19860 }
19861
19862 11 void rebuild_trans_table()
19863 {
19864 11 refresh_rgb_tables();
19865 11 zq_rgb_table = rgb_table;
19866 11 }
19867
19868 int32_t isFullScreen()
19869 {
19870 return !is_windowed_mode();
19871 }
19872
19873 void hit_close_button()
19874 {
19875 close_button_quit=true;
19876 return;
19877 }
19878
19879 extern bool dirty_screen;
19880
19881 void anim_hw_screen()
19882 {
19883 ++cpoolbrush_index;
19884
19885 if(prv_mode)
19886 {
19887 if(Map.get_prvtime())
19888 {
19889 Map.set_prvtime(Map.get_prvtime()-1);
19890
19891 if(!Map.get_prvtime())
19892 {
19893 prv_warp=1;
19894 }
19895 }
19896 }
19897 if(AnimationOn)
19898 {
19899 animate_combos();
19900 update_freeform_combos();
19901 }
19902
19903 if(CycleOn)
19904 cycle_palette();
19905
19906 animate_coords();
19907 update_hw_screen();
19908 }
19909
19910 void custom_vsync()
19911 {
19912 anim_hw_screen();
19913 }
19914
19915 void switch_out()
19916 {
19917 zcmusic_pause(zcmusic, ZCM_PAUSE);
19918 zc_midi_pause();
19919 }
19920
19921 void switch_in()
19922 {
19923 if(exiting_program)
19924 return;
19925 zcmusic_pause(zcmusic, ZCM_RESUME);
19926 zc_midi_resume();
19927 }
19928
19929 void Z_eventlog(const char *format,...)
19930 {
19931 format=format; //to prevent a compiler warning
19932 }
19933
19934 int32_t get_currdmap()
19935 {
19936 return zinit.start_dmap;
19937 }
19938
19939 int32_t get_dlevel()
19940 {
19941 return DMaps[zinit.start_dmap].level;
19942 }
19943
19944 int32_t get_currscr()
19945 {
19946 return Map.getCurrScr();
19947 }
19948
19949 int32_t get_currmap()
19950 {
19951 return Map.getCurrMap();
19952 }
19953
19954 int32_t get_homescr()
19955 {
19956 return DMaps[zinit.start_dmap].cont;
19957 }
19958
19959 int get_screen_for_world_xy(int x, int y)
19960 {
19961 return -1;
19962 }
19963
19964 int current_item(int item_type, bool checkmagic, bool jinx_check, bool check_bunny)
19965 {
19966 //TODO remove as special case?? -DD
19967 if(item_type==itype_shield)
19968 {
19969 return 2;
19970 }
19971
19972 int id = current_item_id(item_type, checkmagic, jinx_check, check_bunny);
19973 return id > -1 ? itemsbuf[id].level : 0;
19974 }
19975
19976 int current_item_power(int itemtype, bool checkmagic, bool jinx_check, bool check_bunny)
19977 {
19978 if (game)
19979 {
19980 int result = current_item_id(itemtype, checkmagic, jinx_check, check_bunny);
19981 return (result<0) ? 0 : itemsbuf[result].power;
19982 }
19983 return 1;
19984 }
19985
19986 int32_t current_item_id(int32_t itemtype, bool, bool, bool)
19987 {
19988 if (game)
19989 {
19990 int32_t result = -1;
19991 int32_t highestlevel = -1;
19992
19993 for (int32_t i = 0; i < MAXITEMS; i++)
19994 {
19995 if ((zq_ignore_item_ownership || game->get_item(i)) && itemsbuf[i].type == itemtype)
19996 {
19997 if (itemsbuf[i].level >= highestlevel)
19998 {
19999 highestlevel = itemsbuf[i].level;
20000 result = i;
20001 }
20002 }
20003 }
20004 return result;
20005 }
20006 for(int32_t i=0; i<MAXITEMS; i++)
20007 {
20008 if(itemsbuf[i].type==itemtype)
20009 return i;
20010 }
20011
20012 return -1;
20013 }
20014
20015
20016 bool can_use_item(int32_t item_type, int32_t item)
20017 {
20018 //these are here to bypass compiler warnings about unused arguments
20019 item_type=item_type;
20020 item=item;
20021
20022 return true;
20023 }
20024
20025 bool has_item(int32_t item_type, int32_t it)
20026 {
20027 //these are here to bypass compiler warnings about unused arguments
20028 item_type=item_type;
20029 it=it;
20030
20031 return true;
20032 }
20033
20034 int32_t get_bmaps(int32_t si)
20035 {
20036 //these are here to bypass compiler warnings about unused arguments
20037 si=si;
20038
20039 return 255;
20040 }
20041
20042 bool no_subscreen()
20043 {
20044 return false;
20045 }
20046
20047 12 static void allocate_crap()
20048 {
20049 12 filepath=(char*)malloc(2048);
20050 12 datapath=(char*)malloc(2048);
20051 12 midipath=(char*)malloc(2048);
20052 12 imagepath=(char*)malloc(2048);
20053 12 tmusicpath=(char*)malloc(2048);
20054 12 last_timed_save=(char*)malloc(2048);
20055
20056
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if(!filepath || !datapath || !imagepath || !midipath || !tmusicpath || !last_timed_save)
20057 {
20058 Z_error_fatal("Error: no memory for file paths!");
20059 }
20060
20061
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<WAV_COUNT; i++)
20062 {
20063
1/4
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3072 if(sfx_string[i]!=NULL) delete sfx_string[i];
20064 3072 customsfxdata[i].data=NULL;
20065 3072 sfx_string[i] = new char[36];
20066 3072 memset(sfx_string[i], 0, 36);
20067 3072 }
20068
20069
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<MAXWPNS; i++)
20070 {
20071
1/4
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3072 if(weapon_string[i]!=NULL) delete weapon_string[i];
20072 3072 weapon_string[i] = new char[64];
20073 3072 memset(weapon_string[i], 0, 64);
20074 3072 }
20075
20076
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<MAXITEMS; i++)
20077 {
20078
1/4
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3072 if(item_string[i]!=NULL) delete item_string[i];
20079 3072 item_string[i] = new char[64];
20080 3072 memset(item_string[i], 0, 64);
20081 3072 }
20082
20083
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for(int32_t i=0; i<eMAXGUYS; i++)
20084 {
20085
1/4
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6144 if(guy_string[i]!=NULL) delete guy_string[i];
20086 6144 guy_string[i] = new char[64];
20087 6144 memset(guy_string[i], 0, 64);
20088 6144 }
20089
20090
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for(int32_t i=0; i<NUMSCRIPTFFC; i++)
20091 {
20092
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6144 times.
6144 delete ffscripts[i];
20093
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 ffscripts[i] = new script_data(ScriptType::FFC, i);
20094 6144 }
20095
20096
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTITEM; i++)
20097 {
20098
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete itemscripts[i];
20099
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 itemscripts[i] = new script_data(ScriptType::Item, i);
20100 3072 }
20101
20102
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTGUYS; i++)
20103 {
20104
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete guyscripts[i];
20105
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 guyscripts[i] = new script_data(ScriptType::NPC, i);
20106 3072 }
20107
20108
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTSCREEN; i++)
20109 {
20110
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete screenscripts[i];
20111
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 screenscripts[i] = new script_data(ScriptType::Screen, i);
20112 3072 }
20113
20114
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 12 times.
108 for(int32_t i=0; i<NUMSCRIPTGLOBAL; i++)
20115 {
20116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 delete globalscripts[i];
20117
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 globalscripts[i] = new script_data(ScriptType::Global, i);
20118 96 }
20119
20120
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 12 times.
72 for(int32_t i=0; i<NUMSCRIPTHERO; i++)
20121 {
20122
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 delete playerscripts[i];
20123
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 playerscripts[i] = new script_data(ScriptType::Hero, i);
20124 60 }
20125
20126
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
20127 {
20128
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete lwpnscripts[i];
20129
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 lwpnscripts[i] = new script_data(ScriptType::Lwpn, i);
20130 3072 }
20131
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
20132 {
20133
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3072 times.
3072 delete ewpnscripts[i];
20134
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 ewpnscripts[i] = new script_data(ScriptType::Ewpn, i);
20135 3072 }
20136
20137
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTSDMAP; i++)
20138 {
20139
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete dmapscripts[i];
20140
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 dmapscripts[i] = new script_data(ScriptType::DMap, i);
20141 3072 }
20142
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTSITEMSPRITE; i++)
20143 {
20144
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 delete itemspritescripts[i];
20145
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 itemspritescripts[i] = new script_data(ScriptType::ItemSprite, i);
20146 3072 }
20147
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for(int32_t i=0; i<NUMSCRIPTSCOMBODATA; i++)
20148 {
20149
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 delete comboscripts[i];
20150
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 comboscripts[i] = new script_data(ScriptType::Combo, i);
20151 6144 }
20152
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for(int32_t i=0; i<NUMSCRIPTSGENERIC; i++)
20153 {
20154
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 delete genericscripts[i];
20155
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 genericscripts[i] = new script_data(ScriptType::Generic, i);
20156 6144 }
20157
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 12 times.
3084 for(int32_t i=0; i<NUMSCRIPTSSUBSCREEN; i++)
20158 {
20159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3072 times.
3072 delete subscreenscripts[i];
20160
1/2
✓ Branch 0 taken 3072 times.
✗ Branch 1 not taken.
3072 subscreenscripts[i] = new script_data(ScriptType::EngineSubscreen, i);
20161 3072 }
20162 12 }
20163
20164 static void handle_sentry_tags()
20165 {
20166 static bool sentry_first_time = true;
20167
20168 static MapCursor sentry_last_map_cursor;
20169 if (Map.getCursor() != sentry_last_map_cursor || sentry_first_time)
20170 {
20171 sentry_last_map_cursor = Map.getCursor();
20172 zapp_reporting_set_tag("cursor.map", sentry_last_map_cursor.map);
20173 zapp_reporting_set_tag("cursor.screen", sentry_last_map_cursor.screen);
20174 zapp_reporting_set_tag("cursor.viewscr", sentry_last_map_cursor.viewscr);
20175 zapp_reporting_set_tag("cursor.size", sentry_last_map_cursor.size);
20176 }
20177
20178 static bool sentry_last_is_compact;
20179 if (is_compact != sentry_last_is_compact || sentry_first_time)
20180 {
20181 sentry_last_is_compact = is_compact;
20182 zapp_reporting_set_tag("compact", sentry_last_is_compact);
20183 }
20184
20185 sentry_first_time = false;
20186 }
20187
20188 int32_t Awpn=-1, Bwpn=-1, Xwpn = -1, Ywpn = -1;
20189 84 sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations, portals;
20190 int32_t exittimer = 10000, exittimer2 = 100;
20191
20192 template <typename ...Params>
20193 [[noreturn]] void FatalConsole(const char *format, Params&&... params)
20194 {
20195 FFCore.ZScriptConsole(CConsoleLoggerEx::COLOR_RED|CConsoleLoggerEx::COLOR_INTENSITY|CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"");
20196 Z_error_fatal(format, std::forward<Params>(params)...);
20197 }
20198
20199 5 static BITMAP* load_asset_bmp(const char* path)
20200 {
20201 5 BITMAP* bmp = load_bmp(path, nullptr);
20202
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (!bmp)
20203 Z_error_fatal("Failed to load required asset: %s\n", path);
20204 5 return bmp;
20205 }
20206
20207 1 static void load_asset_pal(PALETTE pal, const char* path)
20208 {
20209 1 BITMAP* bmp = load_bmp(path, pal);
20210
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!bmp)
20211 Z_error_fatal("Failed to load required asset: %s\n", path);
20212 1 }
20213
20214 1 static MIDI* load_asset_midi(const char* path)
20215 {
20216 1 MIDI* midi = load_midi(path);
20217
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!midi)
20218 Z_error_fatal("Failed to load required asset: %s\n", path);
20219 1 return midi;
20220 }
20221
20222 BITMAP* asset_icons_bmp;
20223 BITMAP* asset_engravings_bmp;
20224 BITMAP* asset_mouse_bmp;
20225 BITMAP* asset_select_bmp;
20226 BITMAP* asset_arrows_bmp;
20227 MIDI* asset_tunes_midi;
20228 PALETTE asset_pal;
20229
20230 1 static void load_assets()
20231 {
20232 1 asset_icons_bmp = load_asset_bmp("assets/editor/icons.bmp");
20233 1 asset_engravings_bmp = load_asset_bmp("assets/editor/engravings.bmp");
20234 1 asset_mouse_bmp = load_asset_bmp("assets/editor/mouse.bmp");
20235 1 asset_select_bmp = load_asset_bmp("assets/editor/select.bmp");
20236 1 asset_arrows_bmp = load_asset_bmp("assets/editor/arrows.bmp");
20237 1 asset_tunes_midi = load_asset_midi("assets/editor/tunes.mid");
20238 1 load_asset_pal(asset_pal, "assets/editor/pal.bmp");
20239 1 }
20240
20241 static bool application_has_loaded;
20242
20243 void do_dev_qrs_zscript_command(string const& fname);
20244
20245 1 int32_t main(int32_t argc,char **argv)
20246 {
20247
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (used_switch(argc, argv, "-test-zc"))
20248 1 set_headless_mode();
20249
20250 1 zalleg_setup_allegro(App::zquest, argc, argv);
20251 1 allocate_crap();
20252
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 set_should_zprint_cb([]() {
20253 return get_qr(qr_SCRIPTERRLOG) || DEVLEVEL > 0;
20254 });
20255
20256 1 Z_title("ZQuest Classic Editor, %s", getVersionString());
20257
20258
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!get_qst_buffers())
20259 {
20260 Z_error_fatal("Error");
20261 }
20262
20263 1 undocombobuf.clear();
20264 1 undocombobuf.resize(MAXCOMBOS);
20265
20266
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((newundotilebuf=(tiledata*)malloc(NEWMAXTILES*sizeof(tiledata)))==NULL)
20267 {
20268 Z_error_fatal("Error: no memory for tile undo buffer!");
20269 }
20270
20271 1 memset(newundotilebuf, 0, NEWMAXTILES*sizeof(tiledata));
20272 1 newtilebuf = (tiledata*)malloc(NEWMAXTILES*sizeof(tiledata));
20273
20274
2/2
✓ Branch 0 taken 2574000 times.
✓ Branch 1 taken 1 times.
2574001 for(int32_t j=0; j<NEWMAXTILES; j++)
20275 2574000 newtilebuf[j].data=NULL;
20276
20277 1 zc_srand(time(0));
20278
20279 1 zeditor_handle_commands();
20280
20281 1 three_finger_flag=false;
20282
20283 #ifndef __EMSCRIPTEN__
20284
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(zc_get_config("zquest","open_debug_console",0))
20285 initConsole();
20286 #endif
20287
20288 LOCK_VARIABLE(lastfps);
20289
20290 LOCK_VARIABLE(framecnt);
20291 LOCK_FUNCTION(fps_callback);
20292
20293
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(install_int_ex(fps_callback,SECS_TO_TIMER(1)))
20294 {
20295 Z_error_fatal("couldn't allocate timer");
20296 }
20297
20298
20299 LOCK_VARIABLE(dclick_status);
20300 LOCK_VARIABLE(dclick_time);
20301 1 lock_dclick_function();
20302 1 install_int(dclick_check, 20);
20303
20304 1 set_gfx_mode(GFX_TEXT,80,50,0,0);
20305
20306 1 load_assets();
20307
20308 1 Z_message("OK\n");
20309
20310
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 helpstr = util::read_text_file("docs/zquest.txt");
20311
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 zstringshelpstr = util::read_text_file("docs/zstrings.txt");
20312
20313 // loading data files...
20314
20315 1 filepath[0]=temppath[0]=0;
20316
20317 1 const char *default_path="";
20318
20319 1 strcpy(datapath,zc_get_config("zquest",data_path_name,default_path));
20320 1 strcpy(midipath,zc_get_config("zquest",midi_path_name,default_path));
20321 1 strcpy(imagepath,zc_get_config("zquest",image_path_name,default_path));
20322 1 strcpy(tmusicpath,zc_get_config("zquest",tmusic_path_name,default_path));
20323 1 chop_path(datapath);
20324 1 chop_path(midipath);
20325 1 chop_path(imagepath);
20326 1 chop_path(tmusicpath);
20327
20328 1 DisableLPalShortcuts = zc_get_config("zquest","dis_lpal_shortcut",1);
20329 1 DisableCompileConsole = zc_get_config("zquest","internal_compile_console",0);
20330 1 MouseScroll = zc_get_config("zquest","mouse_scroll",0);
20331 1 MMapCursorStyle = zc_get_config("zquest","cursorblink_style",1);
20332 1 LayerDitherBG = zc_get_config("zquest", "layer_dither_bg", -1);
20333 1 LayerDitherSz = zc_get_config("zquest", "layer_dither_sz", 3);
20334 1 InvalidBG = zc_get_config("zquest", "invalid_bg", 0);
20335 1 TileProtection = zc_get_config("zquest","tile_protection",1);
20336 1 ComboProtection = zc_get_config("zquest","combo_protection",TileProtection);
20337 1 ShowGrid = zc_get_config("zquest","show_grid",0);
20338 1 ShowCurScreenOutline = zc_get_config("zquest","show_current_screen_outline",1);
20339 1 ShowScreenGrid = zc_get_config("zquest","show_screen_grid",0);
20340 1 ShowRegionGrid = zc_get_config("zquest","show_region_grid",1);
20341 1 HighQualityScreenRendering = zc_get_config("zquest","high_quality_screen_rendering",1);
20342 1 GridColor = zc_get_config("zquest","grid_color",15);
20343 1 CmbCursorCol = zc_get_config("zquest","combo_cursor_color",15);
20344 1 TilePgCursorCol = zc_get_config("zquest","tpage_cursor_color",15);
20345 1 CmbPgCursorCol = zc_get_config("zquest","cpage_cursor_color",15);
20346 1 TTipHLCol = zc_get_config("zquest","ttip_hl_color",13);
20347 1 CheckerCol1 = zc_get_config("zquest","checker_color_1",7);
20348 1 CheckerCol2 = zc_get_config("zquest","checker_color_2",8);
20349 1 SnapshotFormat = zc_get_config("zquest","snapshot_format",3);
20350 1 SnapshotScale = zc_get_config("zquest","snapshot_scale",2);
20351 1 SavePaths = zc_get_config("zquest","save_paths",1);
20352 1 CycleOn = zc_get_config("zquest","cycle_on",1);
20353 1 ShowFPS = zc_get_config("zquest","showfps",0)!=0;
20354 1 SaveDragResize = zc_get_config("zquest","save_drag_resize",0)!=0;
20355 1 DragAspect = zc_get_config("zquest","drag_aspect",0)!=0;
20356 1 SaveWinPos = zc_get_config("zquest","save_window_position",0)!=0;
20357 1 ComboBrush = zc_get_config("zquest","combo_brush",0);
20358 1 FloatBrush = zc_get_config("zquest","float_brush",0);
20359 1 AutoBrush = zc_get_config("zquest","autobrush",1);
20360 1 LinkedScroll = zc_get_config("zquest","linked_comboscroll",0);
20361 1 allowHideMouse = zc_get_config("ZQ_GUI","allowHideMouse",0);
20362 1 ShowFavoriteComboModes = zc_get_config("ZQ_GUI","show_fav_combo_modes",1);
20363 1 NoHighlightLayer0 = zc_get_config("zquest","no_highlight_layer0",0);
20364 1 RulesetDialog = zc_get_config("zquest","rulesetdialog",1);
20365 1 EnableTooltips = zc_get_config("zquest","enable_tooltips",1);
20366 1 TooltipsHighlight = zc_get_config("zquest","ttip_highlight",1);
20367 1 tooltip_maxtimer = vbound(zc_get_config("zquest","ttip_timer",30),0,60*60);
20368 1 ShowFFScripts = zc_get_config("zquest","showffscripts",1);
20369 1 ShowSquares = zc_get_config("zquest","showsquares",1);
20370 1 ShowFFCs = zc_get_config("zquest","showffcs",0);
20371 1 ShowInfo = zc_get_config("zquest","showinfo",1);
20372 1 skipLayerWarning = zc_get_config("zquest","skip_layer_warning",0);
20373 1 numericalFlags = zc_get_config("zquest","numerical_flags",0);
20374 1 ViewLayer2BG = zc_get_config("zquest","layer2_bg",0);
20375 1 ViewLayer3BG = zc_get_config("zquest","layer3_bg",0);
20376 1 ActiveLayerHighlight = zc_get_config("zquest","hl_active_lyr",0);
20377 1 DragCenterOfSquares = zc_get_config("zquest","drag_squares_from_center",0);
20378 1 SmartFFCPlacement = zc_get_config("zquest","smart_ffc_placement",0);
20379
20380 1 OpenLastQuest = zc_get_config("zquest","open_last_quest",0);
20381 1 ShowMisalignments = zc_get_config("zquest","show_misalignments",0);
20382 1 AnimationOn = zc_get_config("zquest","animation_on",1);
20383 1 AutoBackupRetention = zc_get_config("zquest","auto_backup_retention",2);
20384 1 AutoSaveInterval = zc_get_config("zquest","auto_save_interval",6);
20385 1 AutoSaveRetention = zc_get_config("zquest","auto_save_retention",2);
20386 1 UncompressedAutoSaves = zc_get_config("zquest","uncompressed_auto_saves",1);
20387 1 OverwriteProtection = zc_get_config("zquest","overwrite_prevention",0)!=0;
20388 1 ImportMapBias = zc_get_config("zquest","import_map_bias",0);
20389
20390 1 KeyboardRepeatDelay = zc_get_config("zquest","keyboard_repeat_delay",300);
20391 1 KeyboardRepeatRate = zc_get_config("zquest","keyboard_repeat_rate",80);
20392
20393 // Frameskip = zc_get_config("zquest","frameskip",0); //todo: this is not actually supported yet.
20394 1 RequestedFPS = zc_get_config("zquest","fps",60);
20395
20396 // Autofill for Combo Page, Tile Page
20397 1 PreFillTileEditorPage = zc_get_config("zquest","PreFillTileEditorPage",0);
20398 1 PreFillComboEditorPage = zc_get_config("zquest","PreFillComboEditorPage",0);
20399
20400 1 pixeldb = zc_get_config("ZQ_GUI","bottom_8_pixels",0);
20401 1 infobg = zc_get_config("ZQ_GUI","info_text_bg",0);
20402
20403 1 large_merged_combopane = zc_get_config("ZQ_GUI","merge_cpane_large",0);
20404 1 compact_merged_combopane = zc_get_config("ZQ_GUI","merge_cpane_compact",1);
20405
20406 1 compact_square_panels = zc_get_config("ZQ_GUI","square_panels_compact",0);
20407
20408 1 large_zoomed_fav = zc_get_config("ZQ_GUI","zoom_fav_large",0);
20409 1 compact_zoomed_fav = zc_get_config("ZQ_GUI","zoom_fav_compact",1);
20410 1 large_zoomed_cmd = zc_get_config("ZQ_GUI","zoom_cmd_large",1);
20411 1 compact_zoomed_cmd = zc_get_config("ZQ_GUI","zoom_cmd_compact",1);
20412
20413
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(zc_get_config("gui","disable_window_resizing",0))
20414 all_set_resize_flag(false);
20415
20416 1 load_hotkeys();
20417
20418 #ifdef _WIN32
20419 zqUseWin32Proc = zc_get_config("zquest","zq_win_proc_fix",0);
20420
20421 #endif
20422
20423
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!render_timer_start())
20424 {
20425 Z_error_fatal("couldn't allocate timer");
20426 }
20427
20428 1 byte layermask = zc_get_config("zquest","layer_mask",0x7F);
20429 1 int32_t usefullscreen = zc_get_config("zquest","fullscreen",0);
20430 1 tempmode = (usefullscreen == 0 ? GFX_AUTODETECT_WINDOWED : GFX_AUTODETECT_FULLSCREEN);
20431
20432
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 1 times.
8 for(int32_t x=0; x<7; x++)
20433 {
20434 7 LayerMaskInt[x]=get_bit(&layermask,x);
20435 7 }
20436
20437 1 DuplicateAction[0] = zc_get_config("zquest","normal_duplicate_action",2);
20438 1 DuplicateAction[1] = zc_get_config("zquest","horizontal_duplicate_action",0);
20439 1 DuplicateAction[2] = zc_get_config("zquest","vertical_duplicate_action",0);
20440 1 DuplicateAction[3] = zc_get_config("zquest","both_duplicate_action",0);
20441 1 LeechUpdate = zc_get_config("zquest","leech_update",500);
20442 1 LeechUpdateTiles = zc_get_config("zquest","leech_update_tiles",1);
20443 1 OnlyCheckNewTilesForDuplicates = zc_get_config("zquest","only_check_new_tiles_for_duplicates",0);
20444 //gui_colorset = zc_get_config("zquest","gui_colorset",0);
20445
20446 1 strcpy(last_timed_save,zc_get_config("zquest","last_timed_save",""));
20447
20448 1 midi_volume = zc_get_config("zquest", "midi", 255);
20449
20450 1 abc_patternmatch = zc_get_config("zquest", "lister_pattern_matching", 1);
20451 1 NoScreenPreview = zc_get_config("zquest", "no_preview", 0);
20452
20453 1 monochrome_console = zc_get_config("CONSOLE","monochrome_debuggers",0)?1:0;
20454
20455 1 try_recovering_missing_scripts = 0;//zc_get_config("Compiler", "try_recovering_missing_scripts",0);
20456 //We need to remove all of the zeldadx refs to the config file for zquest.
20457
20458 1 set_keyboard_rate(KeyboardRepeatDelay,KeyboardRepeatRate);
20459
20460 1 is_compact = zc_get_config("ZQ_GUI","compact_mode",1);
20461 1 mapscreenbmp = nullptr;
20462 1 brushbmp = nullptr;
20463 1 brushscreen = nullptr;
20464 1 screen2 = nullptr;
20465
20466
2/2
✓ Branch 0 taken 1260 times.
✓ Branch 1 taken 1 times.
1261 for(int32_t i=0; i<MAXFAVORITECOMBOS; ++i)
20467 {
20468 1260 favorite_combos[i]=-1;
20469 1260 }
20470 1 FavoriteComboPage = 0;
20471
20472
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(used_switch(argc,argv,"-d"))
20473 {
20474 set_debug(!strcmp(zquestpwd,zc_get_config("zquest","debug_this","")));
20475 }
20476
20477 1 zcmusic_init();
20478 1 zcmixer = zcmixer_create();
20479 24 install_int_ex([](){ zcmusic_poll(); }, MSEC_TO_TIMER(25));
20480
20481 1 set_color_depth(8);
20482
20483 1 set_close_button_callback((void (*)()) hit_close_button);
20484
20485
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(used_switch(argc,argv,"-fullscreen"))
20486 {
20487 tempmode = GFX_AUTODETECT_FULLSCREEN;
20488 }
20489
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 else if(used_switch(argc,argv,"-windowed"))
20490 {
20491 tempmode=GFX_AUTODETECT_WINDOWED;
20492 }
20493
20494 1 zq_screen_w = LARGE_W;
20495 1 zq_screen_h = LARGE_H;
20496 1 window_width = zc_get_config("zquest","window_width",-1);
20497 1 window_height = zc_get_config("zquest","window_height",-1);
20498 1 auto [w, h] = zc_get_default_display_size(LARGE_W, LARGE_H, window_width, window_height);
20499
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 int32_t videofail = is_headless() ? 0 : (set_gfx_mode(tempmode,w,h,zq_screen_w,zq_screen_h));
20500
20501 //extra block here is intentional
20502
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(videofail!=0)
20503 {
20504 quit_game();
20505 allegro_exit();
20506 }
20507
20508 1 zalleg_create_window();
20509 1 Z_message("gfx mode set at -%d %dbpp %d x %d \n",
20510 1 tempmode, get_color_depth(), zq_screen_w, zq_screen_h);
20511
20512 1 set_window_title("ZC Editor");
20513
20514 1 load_size_poses();
20515
20516
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!is_headless())
20517 {
20518 // Just in case.
20519 while (!all_get_display()) {
20520 al_rest(1);
20521 }
20522
20523 al_resize_display(all_get_display(), w, h);
20524 }
20525
20526
20527 #ifndef __EMSCRIPTEN__
20528
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (!all_get_fullscreen_flag() && !is_headless()) {
20529 al_resize_display(all_get_display(), w, h);
20530
20531 int window_w = al_get_display_width(all_get_display());
20532 int window_h = al_get_display_height(all_get_display());
20533
20534 int new_x = zc_get_config("zquest","window_x",0);
20535 int new_y = zc_get_config("zquest","window_y",0);
20536 if(zc_get_config("zquest","save_window_position",0) && (new_x || new_y))
20537 {
20538 //load saved position
20539 //already stored in new_x/new_y
20540 }
20541 else
20542 {
20543 //Get default position
20544 ALLEGRO_MONITOR_INFO info;
20545 al_get_monitor_info(0, &info);
20546
20547 int mw = (info.x2 - info.x1);
20548 int mh = (info.y2 - info.y1);
20549 new_x = mw / 2 - window_w / 2;
20550 new_y = mh / 2 - window_h / 2;
20551 //Don't spawn the window too far down (taskbar?)
20552 if(new_y + window_h > mh - 72)
20553 new_y = mh-72-window_h;
20554 }
20555 #ifdef ALLEGRO_MACOSX
20556 if (zc_get_config("zquest","save_window_position",0))
20557 al_set_window_position(all_get_display(), new_x, new_y);
20558 #else
20559 al_set_window_position(all_get_display(), new_x, new_y);
20560 #endif
20561 }
20562 #endif
20563
20564 1 position_mouse(zq_screen_w/2,zq_screen_h/2);
20565
20566 1 dmapbmp_small = create_bitmap_ex(8,65,33);
20567 1 dmapbmp_large = create_bitmap_ex(8,177,81);
20568
20569
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!screen2 || !dmapbmp_large || !dmapbmp_large || !brushbmp || !brushscreen)// || !brushshadowbmp )
20570 {
20571 Z_error_fatal("Failed to create system bitmaps!\n");
20572 return 1;
20573 }
20574
20575
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!is_headless())
20576 {
20577 zc_set_palette(asset_pal);
20578 get_palette(RAMpal);
20579 load_colorset(gui_colorset);
20580 zc_set_palette(RAMpal);
20581 clear_to_color(screen,vc(0));
20582 }
20583
20584 1 zScript = string();
20585 1 strcpy(zScriptBytes, "0 Bytes in Buffer");
20586
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
13 for(int32_t i=0; i<MOUSE_BMP_MAX; i++)
20587 {
20588
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 12 times.
60 for(int32_t j=0; j<4; j++)
20589 {
20590 48 mouse_bmp[i][j] = NULL;
20591 48 mouse_bmp_1x[i][j] = NULL;
20592 48 }
20593 12 }
20594 1 load_mice();
20595 1 gui_mouse_focus=0;
20596 1 MouseSprite::set(ZQM_NORMAL);
20597 1 render_zq(); // Ensure the rendering bitmaps are setup.
20598
20599 #ifdef __EMSCRIPTEN__
20600 em_mark_ready_status();
20601 #endif
20602
20603 1 load_icons();
20604
20605 1 bool load_last_timed_save=false;
20606
20607 1 load_recent_quests();
20608 1 refresh_recent_menu();
20609 //clearConsole();
20610
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 if((last_timed_save[0]!=0)&&(exists(last_timed_save)))
20611 {
20612 if (alert_confirm("ZQuest","It appears that ZQuest crashed last time.\nWould you like to load the last timed save?"))
20613 {
20614 int32_t ret = load_quest(last_timed_save);
20615
20616 if(ret == qe_OK)
20617 {
20618 strcpy(filepath,last_timed_save);
20619 load_last_timed_save=true;
20620 mark_save_dirty();
20621 }
20622 else
20623 {
20624 displayinfo("Error","Unable to reload the last timed save.");
20625 }
20626 }
20627 }
20628
20629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!load_last_timed_save)
20630 {
20631 1 strcpy(filepath,zc_get_config("zquest",last_quest_name,""));
20632
20633
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if(argc>1 && argv[1][0]!='-')
20634 {
20635 int32_t ret = load_quest(argv[1]);
20636
20637 if(ret == qe_OK)
20638 {
20639 first_save=true;
20640 strcpy(filepath,argv[1]);
20641 refresh(rALL);
20642 }
20643 }
20644
2/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
1 else if(OpenLastQuest&&filepath[0]&&exists(filepath)&&!used_switch(argc,argv,"-new"))
20645 {
20646 int32_t ret = load_quest(filepath);
20647
20648 if(ret == qe_OK)
20649 {
20650 first_save=true;
20651 refresh(rALL);
20652 }
20653 else
20654 {
20655 filepath[0]=temppath[0]=0;
20656 first_save=false;
20657 }
20658 }
20659 else
20660 {
20661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (onNew() == D_CLOSE)
20662 {
20663 1 Z_message("User canceled creating new quest, closing.\n");
20664 1 exit(0);
20665 }
20666
20667 //otherwise the blank quest gets the name of the last loaded quest... not good! -DD
20668 filepath[0]=temppath[0]=0;
20669 first_save=false;
20670 }
20671 }
20672
20673 if(used_switch(argc,argv,"-q"))
20674 {
20675 Z_message("-q switch used, quitting program.\n");
20676 zq_exit(0);
20677 }
20678
20679 for(int32_t x=0; x<MAXITEMS; x++)
20680 {
20681 lens_hint_item[x][0]=0;
20682 lens_hint_item[x][1]=0;
20683 }
20684
20685 for(int32_t x=0; x<MAXWPNS; x++)
20686 {
20687 lens_hint_weapon[x][0]=0;
20688 lens_hint_weapon[x][1]=0;
20689 }
20690
20691 load_selections();
20692 load_arrows();
20693 DIALOG_PLAYER *player2=init_dialog(dialogs,-1);
20694
20695 get_palette(RAMpal);
20696
20697 rgb_map = zq_rgb_table;
20698
20699 #ifdef __EMSCRIPTEN__
20700 {
20701 int qs_map = EM_ASM_INT({
20702 return new URL(location.href).searchParams.get('map') ?? -1;
20703 });
20704 int qs_screen = EM_ASM_INT({
20705 return new URL(location.href).searchParams.get('screen') ?? -1;
20706 });
20707 if (qs_map != -1 && qs_screen != -1) {
20708 Map.setCurrMap(qs_map);
20709 Map.setCurrScr(qs_screen);
20710 }
20711 }
20712 #endif
20713
20714 // setup_combo_animations();
20715 pause_refresh = false;
20716 refresh_pal();
20717 refresh(rALL);
20718 for(int q = 0; q < brush_width_menu.size(); ++q)
20719 brush_width_menu.at(q)->select(q==0);
20720 for(int q = 0; q < brush_height_menu.size(); ++q)
20721 brush_height_menu.at(q)->select(q==0);
20722 set_filltype(1);
20723
20724 rebuild_trans_table();
20725
20726 if (!is_headless())
20727 {
20728 set_display_switch_mode(SWITCH_BACKGROUND);
20729 set_display_switch_callback(SWITCH_OUT, switch_out);
20730 set_display_switch_callback(SWITCH_IN, switch_in);
20731 }
20732
20733 if(!update_dialog(player2))
20734 exiting_program = true;
20735 //clear_keybuf();
20736 media_menu.disable_uid(MENUID_MEDIA_CHANGETRACK, true);
20737 disable_hotkey(ZQKEY_CHANGE_TRACK, true);
20738
20739 fix_drawing_mode_menu();
20740
20741
20742 #ifdef _WIN32
20743
20744 if(zqUseWin32Proc != FALSE)
20745 {
20746 al_trace("Config file warning: \"zq_win_proc_fix\" enabled switch found. This can cause crashes on some computers.\n");
20747 win32data.zqSetDefaultThreadPriority(0);
20748 win32data.zqSetCustomCallbackProc(al_get_win_window_handle(all_get_display()));
20749 }
20750
20751 #endif
20752
20753 time(&auto_save_time_start);
20754
20755 FFCore.init();
20756 ZQincludePaths = FFCore.includePaths;
20757
20758 Map.setCopyFFC(-1); //Do not have an initial ffc on the clipboard.
20759 brush_menu.select_uid(MENUID_BRUSH_AUTOBRUSH, AutoBrush);
20760 brush_menu.disable_uid(MENUID_BRUSH_WIDTH, AutoBrush);
20761 brush_menu.disable_uid(MENUID_BRUSH_HEIGHT, AutoBrush);
20762 brush_menu.select_uid(MENUID_BRUSH_COMBOBRUSH, ComboBrush);
20763 brush_menu.select_uid(MENUID_BRUSH_FLOATBRUSH, FloatBrush);
20764
20765 application_has_loaded = true;
20766
20767 while(!exiting_program)
20768 {
20769 handle_sentry_tags();
20770
20771 #ifdef _WIN32
20772 if(zqUseWin32Proc != FALSE)
20773 win32data.Update(Frameskip); //experimental win32 fixes
20774 #endif
20775 check_autosave();
20776 ++alignment_arrow_timer;
20777
20778 if(alignment_arrow_timer>63)
20779 {
20780 alignment_arrow_timer=0;
20781 }
20782 ++frame;
20783
20784 file_menu.disable_uid(MENUID_FILE_SAVE, saved||disable_saving||OverwriteProtection);
20785 file_menu.disable_uid(MENUID_FILE_REVERT, saved||disable_saving||OverwriteProtection);
20786 file_menu.disable_uid(MENUID_FILE_SAVEAS, disable_saving);
20787
20788 fixtools_menu.disable_uid(MENUID_FIXTOOL_OLDSTRING,
20789 !(get_qr(qr_OLD_STRING_EDITOR_MARGINS)
20790 ||get_qr(qr_STRING_FRAME_OLD_WIDTH_HEIGHT)));
20791
20792 edit_menu.disable_uid(MENUID_EDIT_UNDO, !Map.CanUndo());
20793 edit_menu.disable_uid(MENUID_EDIT_REDO, !Map.CanRedo());
20794
20795 bool canpaste = Map.CanPaste();
20796 edit_menu.disable_uid(MENUID_EDIT_PASTE, !canpaste);
20797 edit_menu.disable_uid(MENUID_EDIT_PASTEALL, !canpaste);
20798 edit_menu.disable_uid(MENUID_EDIT_ADVPASTE, !canpaste);
20799 edit_menu.disable_uid(MENUID_EDIT_SPECPASTE, !canpaste);
20800 rc_menu_screen.disable_uid(MENUID_RCSCREEN_PASTE, !canpaste);
20801 rc_menu_screen.disable_uid(MENUID_RCSCREEN_ADVPASTE, !canpaste);
20802 rc_menu_screen.disable_uid(MENUID_RCSCREEN_SPECPASTE, !canpaste);
20803 for(MenuItem& mit : paste_menu.inner())
20804 mit.disable(!canpaste);
20805 for(MenuItem& mit : paste_item_menu.inner())
20806 mit.disable(!canpaste);
20807
20808 edit_menu.disable_uid(MENUID_EDIT_COPY, !(Map.CurrScr()->valid&mVALID));
20809 edit_menu.disable_uid(MENUID_EDIT_DELETE, !(Map.CurrScr()->valid&mVALID));
20810
20811 // Are some things selected?
20812 view_menu.select_uid(MENUID_VIEW_WALKABILITY, Flags&cWALK);
20813 view_menu.select_uid(MENUID_VIEW_FLAGS, Flags&cFLAGS);
20814 view_menu.select_uid(MENUID_VIEW_CSET, Flags&cCSET);
20815 view_menu.select_uid(MENUID_VIEW_TYPES, Flags&cCTYPE);
20816 view_menu.select_uid(MENUID_VIEW_INFO, ShowInfo);
20817 view_menu.select_uid(MENUID_VIEW_SQUARES, ShowSquares);
20818 view_menu.select_uid(MENUID_VIEW_FFCS, ShowFFCs);
20819 view_menu.select_uid(MENUID_VIEW_SCRIPTNAMES, ShowFFScripts);
20820 view_menu.select_uid(MENUID_VIEW_GRID, ShowGrid);
20821 view_menu.select_uid(MENUID_VIEW_SCREENGRID, ShowScreenGrid);
20822 view_menu.select_uid(MENUID_VIEW_REGIONGRID, ShowRegionGrid);
20823 view_menu.select_uid(MENUID_VIEW_CURSCROUTLINE, ShowCurScreenOutline);
20824 view_menu.select_uid(MENUID_VIEW_DARKNESS, get_qr(qr_NEW_DARKROOM) && (Flags&cNEWDARK));
20825 view_menu.select_uid(MENUID_VIEW_L2BG, ViewLayer2BG);
20826 view_menu.select_uid(MENUID_VIEW_L3BG, ViewLayer3BG);
20827 view_menu.select_uid(MENUID_VIEW_LAYERHIGHLIGHT, ActiveLayerHighlight);
20828 view_menu.select_uid(MENUID_VIEW_HIGH_QUALITY_SCREEN_RENDERING, HighQualityScreenRendering);
20829
20830 maps_menu.disable_uid(MENUID_MAPS_NEXT, !map_count || Map.getCurrMap() >= map_count);
20831 maps_menu.disable_uid(MENUID_MAPS_PREV, Map.getCurrMap()<=0);
20832
20833 etc_menu.disable_uid(MENUID_ETC_VIDMODE, isFullScreen()==1);
20834 etc_menu.select_uid(MENUID_ETC_FULLSCREEN, isFullScreen()==1);
20835
20836 if(!update_dialog(player2))
20837 exiting_program = true;
20838
20839 //clear_keybuf();
20840 handle_close_btn_quit();
20841 }
20842
20843 zq_exit(0);
20844 return 0;
20845 }
20846 END_OF_MAIN()
20847
20848 11 void zq_exit(int code)
20849 {
20850 11 set_is_exiting();
20851 11 parser_console.kill();
20852 11 killConsole();
20853
20854 11 quit_game();
20855 11 allegro_exit();
20856 11 exit(code);
20857 }
20858
20859 4 void init_bitmap(BITMAP** bmp, int32_t w, int32_t h)
20860 {
20861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(*bmp)
20862 destroy_bitmap(*bmp);
20863 4 *bmp = create_bitmap_ex(8,w,h);
20864 4 clear_bitmap(*bmp);
20865 4 }
20866 1 void load_size_poses()
20867 {
20868 1 ttip_uninstall_all();
20869
20870 1 FONT* favcmdfont = get_custom_font(CFONT_FAVCMD);
20871 1 FONT* guifont = get_custom_font(CFONT_GUI);
20872
20873 1 d_nbmenu_proc(MSG_START, &dialogs[0], 0);
20874
20875 1 commands_list.xscale = command_buttonwidth;
20876 1 commands_list.yscale = 10+text_height(favcmdfont);
20877
20878 1 auto drawmode_wid = 64;
20879
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 for(auto q = 0; q < dm_max; ++q)
20880 {
20881 6 auto wid = text_length(guifont, dm_names[q]);
20882
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(wid > drawmode_wid)
20883 drawmode_wid = wid;
20884 6 }
20885
20886 //Main GUI objects
20887
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(is_compact)
20888 {
20889 1 num_combo_cols = 2;
20890 1 combo_col_scale = 16;
20891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(compact_merged_combopane)
20892 {
20893 1 num_combo_cols = 1;
20894 1 combo_col_scale = 32;
20895 1 }
20896
20897 1 mapscreen_x=0;
20898 1 mapscreen_y=dialogs[0].h;
20899 1 mapscreen_screenunit_scale=3;
20900 1 mapscreen_single_scale = (double)mapscreen_screenunit_scale / Map.getViewSize();
20901 1 showedges=0;
20902 1 showallpanels=0;
20903
20904 1 blackout_color=8;
20905
20906 1 auto mapscr_wid = (((showedges?2:0)+16)*16*mapscreen_screenunit_scale);
20907 1 combolist_window.w=zq_screen_w-mapscr_wid;
20908 1 combolist_window.x=zq_screen_w-combolist_window.w;
20909
20910 1 favorites_window.x=combolist_window.x;
20911 1 favorites_window.w=combolist_window.w;
20912 1 favorites_window.h=136;
20913 1 favorites_window.y=zq_screen_h-favorites_window.h;
20914
20915 1 combolist_window.y=0;
20916 1 combolist_window.h=favorites_window.y-combolist_window.y;
20917
20918 1 combo_preview.x=zq_screen_w-32-8;
20919 1 combo_preview.y=combolist_window.y+6;
20920 1 combo_preview.w=32;
20921 1 combo_preview.h=32;
20922 1 combo_preview2.clear();
20923
20924 1 auto col_wid = 4*combo_col_scale;
20925 1 auto cols_wid = col_wid * num_combo_cols;
20926 1 auto cols_spacing = (combolist_window.w-cols_wid)/(num_combo_cols+1);
20927
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for(auto q = 0; q < num_combo_cols; ++q)
20928 {
20929 1 combolist[q].x=combolist_window.x+(cols_spacing*(q+1))+(col_wid*q);
20930 1 combolist[q].y=combolist_window.y+54;
20931 1 combolist[q].w=4;
20932 1 combolist[q].h=compact_merged_combopane ? 15 : 30;
20933 1 combolist[q].xscale = combo_col_scale;
20934 1 combolist[q].yscale = combo_col_scale;
20935
20936 1 comboaliaslist[q].x = combolist[q].x;
20937 1 comboaliaslist[q].y = combolist[q].y;
20938 1 comboaliaslist[q].w = 4;
20939 1 comboaliaslist[q].h = compact_merged_combopane ? 13 : 26;
20940 1 comboaliaslist[q].xscale = combo_col_scale;
20941 1 comboaliaslist[q].yscale = combo_col_scale;
20942
20943 1 combolistscrollers[q].w=2;
20944 1 combolistscrollers[q].h=1;
20945 1 combolistscrollers[q].xscale=11;
20946 1 combolistscrollers[q].yscale=11;
20947 1 combolistscrollers[q].x=combolist[q].x+(combolist[q].w*combolist[q].xscale/2)-11;
20948 1 combolistscrollers[q].y=combolist[q].y-combolistscrollers[q].th()-3;
20949 1 }
20950
20951 1 comboalias_preview.x=zq_screen_w-((combolist_window.w+64)/2);
20952 1 comboalias_preview.h=64;
20953 1 comboalias_preview.y=favorites_window.y-comboalias_preview.h-8;
20954 1 comboalias_preview.w=64;
20955
20956 1 combo_merge_btn.w = 20;
20957 1 combo_merge_btn.h = 20;
20958 1 combo_merge_btn.x = zq_screen_w-(combolist_window.w+combo_merge_btn.w)/2;
20959 1 combo_merge_btn.y = combolist[0].y-combo_merge_btn.h;
20960
20961
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(num_combo_cols == 1)
20962 {
20963 1 combolistscrollers[0].x += 34;
20964 1 }
20965 1 drawmode_btn.x = combolist_window.x-drawmode_wid;
20966 1 drawmode_btn.y = 0;
20967 1 drawmode_btn.w = drawmode_wid;
20968 1 drawmode_btn.h = mapscreen_y;
20969
20970 1 compactbtn.w = text_length(guifont,"> Compact")+10;
20971 1 compactbtn.x = drawmode_btn.x-compactbtn.w;
20972 1 compactbtn.y = drawmode_btn.y;
20973 1 compactbtn.h = drawmode_btn.h;
20974
20975 1 zoominbtn.w = text_length(guifont,"+")+10;
20976 1 zoominbtn.x = compactbtn.x-zoominbtn.w;
20977 1 zoominbtn.y = compactbtn.y;
20978 1 zoominbtn.h = compactbtn.h;
20979
20980 1 zoomoutbtn.w = text_length(guifont,"-")+10;
20981 1 zoomoutbtn.x = zoominbtn.x-zoomoutbtn.w;
20982 1 zoomoutbtn.y = compactbtn.y;
20983 1 zoomoutbtn.h = compactbtn.h;
20984
20985
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 for(int32_t i=0; i<=8; i++)
20986 {
20987 9 map_page_bar[i].w = 48;
20988 9 map_page_bar[i].x = mapscreen_x+(i*48);
20989 9 map_page_bar[i].y = mapscreen_y+(11*16*mapscreen_screenunit_scale);
20990 9 map_page_bar[i].h = text_height(guifont)+12;
20991 9 }
20992
20993 1 minimap.w=7+48*3;
20994 1 minimap.h=16+27*3;
20995
20996 1 layer_panel.x=map_page_bar[6].x;
20997 1 layer_panel.y=map_page_bar[0].y;
20998 1 layer_panel.w=combolist_window.x - layer_panel.x;
20999 1 layer_panel.h=map_page_bar[0].h;
21000 1 layerpanel_buttonwidth = 51;
21001 1 layerpanel_buttonheight = layer_panel.h;
21002 1 layerpanel_checkbox_hei = layerpanel_buttonheight-4;
21003 1 layerpanel_checkbox_wid = 15;
21004
21005 1 minimap.x=3;
21006 1 minimap.y=layer_panel.y+layer_panel.h+4;
21007
21008 1 real_minimap.x = minimap.x+3;
21009 1 real_minimap.y = minimap.y+5;
21010 1 real_minimap.w = 16;
21011 1 real_minimap.h = 9;
21012 1 real_minimap.xscale = 9;
21013 1 real_minimap.yscale = 9;
21014 1 real_minimap.fw = real_minimap.xscale*8;
21015 1 real_minimap.fh = real_minimap.yscale*8;
21016
21017 1 int upscale_mm = 3;
21018 1 int xwid = real_minimap.tw()*(upscale_mm-1);
21019 1 int xhei = real_minimap.th()*(upscale_mm-1);
21020 1 minimap_zoomed.set(minimap.x, minimap.y-xhei, minimap.w+xwid, minimap.h+xhei+4);
21021 1 real_minimap_zoomed.set(minimap_zoomed.x+3, minimap_zoomed.y+5, real_minimap.w, real_minimap.h, real_minimap.xscale*upscale_mm, real_minimap.yscale*upscale_mm);
21022 1 real_minimap_zoomed.fw = real_minimap_zoomed.xscale*8;
21023 1 real_minimap_zoomed.fh = real_minimap_zoomed.yscale*8;
21024
21025 1 screrrorpos.x = combolist_window.x - 3;
21026 1 screrrorpos.y = layer_panel.y - 16;
21027
21028 1 mouse_scroll_h=10;
21029
21030 1 favorites_list.x=favorites_window.x+8;
21031 1 favorites_list.y=favorites_window.y+16;
21032 1 favorites_list.xscale = 16;
21033 1 favorites_list.yscale = 16;
21034 1 favorites_list.w=(favorites_window.w-16)/favorites_list.xscale;
21035 1 favorites_list.h=(favorites_window.h-24)/favorites_list.yscale;
21036
21037 1 commands_list.w=4;
21038
21039 1 int bh = commands_list.yscale;
21040 1 int bw = 26;
21041 1 commands_window.w=commands_list.w*commands_list.xscale+10+bw;
21042 1 commands_window.x=combolist_window.x-commands_window.w;
21043 1 commands_window.y=layer_panel.y+layer_panel.h;
21044 1 commands_window.h=zq_screen_h-commands_window.y;
21045 1 int bx = commands_window.x+2;
21046
21047 1 commands_list.y=commands_window.y+4;
21048 1 commands_list.h=(zq_screen_h - commands_list.y) / commands_list.yscale;
21049 1 commands_list.x=bx+bw;
21050
21051 1 commands_zoombtn.w = bw;
21052 1 commands_zoombtn.h = bh;
21053 1 commands_zoombtn.x = bx;
21054 1 commands_zoombtn.y = commands_list.y;
21055
21056 1 commands_infobtn.w = bw;
21057 1 commands_infobtn.h = bh;
21058 1 commands_infobtn.x = bx;
21059 1 commands_infobtn.y = commands_zoombtn.y + commands_infobtn.h;
21060
21061 1 commands_x.w = bw;
21062 1 commands_x.h = bh;
21063 1 commands_x.x = bx;
21064 1 commands_x.y = commands_infobtn.y + commands_x.h;
21065
21066 1 commands_txt.clear();
21067
21068 1 main_panel.x = 0;
21069 1 main_panel.y = layer_panel.y+layer_panel.h;
21070 1 main_panel.w = commands_window.x - main_panel.x;
21071 1 main_panel.h = 76+32;
21072 1 preview_panel = main_panel;
21073 1 preview_panel.x = 0;
21074 1 preview_panel.w = commands_window.x - preview_panel.x;
21075
21076 1 preview_text.x = preview_panel.x+3;
21077 1 preview_text.y = preview_panel.y+3;
21078 1 preview_text.w = 2;
21079 1 preview_text.h = 6;
21080 1 preview_text.xscale = 10;
21081 1 preview_text.yscale = text_height(get_zc_font(font_lfont_l));
21082
21083 1 panel_align = 1;
21084 1 int swapbtnw = 32, swapbtnh = 20;
21085 1 int swapbtnx = main_panel.x+main_panel.tw()-swapbtnw;
21086 1 squarepanel_swap_btn.set(swapbtnx, zq_screen_h-swapbtnh, swapbtnw, swapbtnh);
21087
21088 1 int sqx = minimap.x+minimap.tw();
21089 1 squares_panel.set(sqx,main_panel.y,main_panel.tw()-sqx,main_panel.th());
21090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(compact_square_panels)
21091 {
21092 int cmpy = main_panel.y+(main_panel.th()/2);
21093 squarepanel_up_btn.set(swapbtnx, cmpy-swapbtnh, swapbtnw, swapbtnh);
21094 squarepanel_down_btn.set(swapbtnx, cmpy, swapbtnw, swapbtnh);
21095
21096 txtoffs_single.x = 18;
21097 txtoffs_single.y = 36;
21098 txtoffs_double_1.x = 18;
21099 txtoffs_double_1.y = 36;
21100 txtoffs_double_2.x = 18;
21101 txtoffs_double_2.y = 36 + text_height(get_custom_font(CFONT_GUI));
21102
21103 //Clear them all- if they stay cleared, they are invisible.
21104 itemsqr_pos.clear();
21105 stairsqr_pos.clear();
21106 warparrival_pos.clear();
21107 flagsqr_pos.clear();
21108 enemy_prev_pos.clear();
21109 for(int q = 0; q < 4; ++q)
21110 warpret_pos[q].clear();
21111
21112 int sqr_x1 = sqx+12;
21113 int sqr_y1 = main_panel.y+12;
21114 int sqr_xoffs = (16*2)+4 + 12;
21115 switch(compact_active_panel)
21116 {
21117 case 0: //Warp Squares
21118 {
21119 int x = sqr_x1;
21120 for(int q = 0; q < 4; ++q)
21121 {
21122 warpret_pos[q].set(x,sqr_y1,(16*2)+4,(16*2)+4);
21123 x += sqr_xoffs;
21124 }
21125 break;
21126 }
21127 case 1: //Other Squares
21128 {
21129 itemsqr_pos.set(sqr_x1+(sqr_xoffs*0), sqr_y1, (16*2)+4,(16*2)+4);
21130 stairsqr_pos.set(sqr_x1+(sqr_xoffs*1), sqr_y1, (16*2)+4,(16*2)+4);
21131 warparrival_pos.set(sqr_x1+(sqr_xoffs*2), sqr_y1, (16*2)+4,(16*2)+4);
21132 flagsqr_pos.set(sqr_x1+(sqr_xoffs*3), sqr_y1, (16*2)+4,(16*2)+4);
21133 break;
21134 }
21135 case 2: //Enemy Preview
21136 {
21137 enemy_prev_pos.set(sqr_x1, sqr_y1, 5, 2, 32, 32);
21138 break;
21139 }
21140 }
21141 }
21142 else
21143 {
21144 1 squarepanel_up_btn.clear();
21145 1 squarepanel_down_btn.clear();
21146 1 txtoffs_single.x = 10;
21147 1 txtoffs_single.y = 22;
21148 1 txtoffs_double_1.x = 10;
21149 1 txtoffs_double_1.y = 22;
21150 1 txtoffs_double_2.x = 10;
21151 1 txtoffs_double_2.y = 30;
21152
21153
21154 1 int sqr_x1 = sqx+24;
21155 1 int sqr_y1 = main_panel.y+12;
21156 1 int sqr_y2 = sqr_y1+42;
21157 1 int sqr_xdist = 32;
21158 1 itemsqr_pos.set(sqr_x1+(sqr_xdist*0),sqr_y1,20,20);
21159 1 stairsqr_pos.set(sqr_x1+(sqr_xdist*1),sqr_y1,20,20);
21160 1 warparrival_pos.set(sqr_x1+(sqr_xdist*2),sqr_y1,20,20);
21161 1 flagsqr_pos.set(sqr_x1+(sqr_xdist*3),sqr_y1,20,20);
21162
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 for(auto q = 0; q < 4; ++q)
21163 {
21164 4 warpret_pos[q].set(sqr_x1+(sqr_xdist*q),sqr_y2,20,20);
21165 4 }
21166 1 enemy_prev_pos.set(sqr_x1+(sqr_xdist*4), sqr_y1, 4, 3, 16, 16);
21167 1 enemy_prev_pos.fw = enemy_prev_pos.xscale*2;
21168 1 enemy_prev_pos.fh = enemy_prev_pos.yscale*2;
21169 }
21170
21171 1 auto& last_alias_list = comboaliaslist[num_combo_cols-1];
21172 1 combopool_preview.x=comboaliaslist[0].x;
21173 1 combopool_preview.y=last_alias_list.y+(last_alias_list.h*last_alias_list.yscale)+16;
21174 1 combopool_preview.w=(last_alias_list.x+(last_alias_list.w*last_alias_list.xscale))-comboaliaslist[0].x;
21175 1 combopool_preview.h=zq_screen_h-8-combopool_preview.y;
21176 1 combopool_preview.w -= combopool_preview.w%16;
21177 1 combopool_preview.h -= combopool_preview.h%16;
21178
21179 1 FONT* tfont = get_zc_font(font_lfont_l);
21180 1 combopool_prevbtn.w = text_length(tfont, "Unweighted")+10;
21181 1 combopool_prevbtn.h = 11;
21182 1 combopool_prevbtn.x = combopool_preview.x;
21183 1 combopool_prevbtn.y = combopool_preview.y-combopool_prevbtn.h;
21184
21185 1 mappage_count = 6;
21186
21187 1 txfont = get_zc_font(font_lfont_l);
21188 1 combo_preview_text1.set(combo_preview.x-5,combo_preview.y,1,3,1,text_height(txfont));
21189 1 combo_preview_text2.clear();
21190
21191 1 favorites_x.w = 17;
21192 1 favorites_infobtn.w = 17;
21193 1 favorites_zoombtn.w = 17;
21194 1 favorites_pgleft.w = 17;
21195 1 favorites_pgright.w = 17;
21196 1 }
21197 else
21198 {
21199 num_combo_cols = 4;
21200 combo_col_scale = 16;
21201 if(large_merged_combopane)
21202 {
21203 num_combo_cols = 2;
21204 combo_col_scale = 32;
21205 }
21206
21207 mapscreen_x=0;
21208 mapscreen_y=dialogs[0].h;
21209 mapscreen_screenunit_scale=2;
21210 mapscreen_single_scale = (double)mapscreen_screenunit_scale / Map.getViewSize();
21211 if (HighQualityScreenRendering)
21212 showedges=Map.getViewSize() == 1 ? 1 : 0;
21213 else
21214 showedges=Map.getViewSize() <= 2 ? 1 : 0;
21215 showallpanels=0;
21216
21217 blackout_color=8;
21218
21219 favorites_window.h=136;
21220 favorites_window.y=zq_screen_h-favorites_window.h;
21221
21222 auto mapscr_wid = (((2)+16)*16*mapscreen_screenunit_scale);
21223 combolist_window.w=zq_screen_w-mapscr_wid;
21224 combolist_window.x=zq_screen_w-combolist_window.w;
21225 combolist_window.y=0;
21226 combolist_window.h=favorites_window.y-combolist_window.y;
21227
21228 favorites_window.x=combolist_window.x;
21229 favorites_window.w=combolist_window.w;
21230
21231 combo_preview.x=(zq_screen_w-(combolist_window.w/2))-40;
21232 combo_preview.y=combolist_window.y+6;
21233 combo_preview.w=32;
21234 combo_preview.h=32;
21235 combo_preview2 = combo_preview;
21236 combo_preview2.x += 48;
21237
21238 auto col_wid = 4*combo_col_scale;
21239 auto cols_wid = col_wid * num_combo_cols;
21240 auto cols_spacing = (combolist_window.w-cols_wid)/(num_combo_cols+1);
21241 for(auto q = 0; q < num_combo_cols; ++q)
21242 {
21243 combolist[q].x=combolist_window.x+(cols_spacing*(q+1))+(col_wid*q);
21244 combolist[q].y=combolist_window.y+60;
21245 combolist[q].w=4;
21246 combolist[q].h=large_merged_combopane ? 15 : 30;
21247 combolist[q].xscale = combo_col_scale;
21248 combolist[q].yscale = combo_col_scale;
21249
21250 comboaliaslist[q].x=combolist[q].x;
21251 comboaliaslist[q].y=combolist[q].y;
21252 comboaliaslist[q].w=4;
21253 comboaliaslist[q].h=large_merged_combopane ? 12 : 25;
21254 comboaliaslist[q].xscale = combo_col_scale;
21255 comboaliaslist[q].yscale = combo_col_scale;
21256
21257 combolistscrollers[q].w=2;
21258 combolistscrollers[q].h=1;
21259 combolistscrollers[q].xscale=11;
21260 combolistscrollers[q].yscale=11;
21261 combolistscrollers[q].x=combolist[q].x+(combolist[q].w*combolist[q].xscale/2)-11;
21262 combolistscrollers[q].y=combolist[q].y-combolistscrollers[q].th()-2;
21263 }
21264
21265 comboalias_preview.x=zq_screen_w-((combolist_window.w+64)/2);
21266 comboalias_preview.h=64;
21267 comboalias_preview.w=64;
21268 comboalias_preview.y=favorites_window.y-comboalias_preview.h-8;
21269
21270 combo_merge_btn.w = 20;
21271 combo_merge_btn.h = 20;
21272 combo_merge_btn.x = zq_screen_w-(combolist_window.w+combo_merge_btn.w)/2;
21273 combo_merge_btn.y = combolist[0].y-combo_merge_btn.h;
21274 squarepanel_swap_btn.clear();
21275 squarepanel_up_btn.clear();
21276 squarepanel_down_btn.clear();
21277
21278 drawmode_btn.x = combolist_window.x-drawmode_wid;
21279 drawmode_btn.y = 0;
21280 drawmode_btn.w = drawmode_wid;
21281 drawmode_btn.h = mapscreen_y;
21282
21283 compactbtn.w = text_length(guifont,"> Compact")+10;
21284 compactbtn.x = drawmode_btn.x-compactbtn.w;
21285 compactbtn.y = drawmode_btn.y;
21286 compactbtn.h = drawmode_btn.h;
21287
21288 zoominbtn.w = text_length(guifont,"+")+10;
21289 zoominbtn.x = compactbtn.x-zoominbtn.w;
21290 zoominbtn.y = compactbtn.y;
21291 zoominbtn.h = compactbtn.h;
21292
21293 zoomoutbtn.w = text_length(guifont,"-")+10;
21294 zoomoutbtn.x = zoominbtn.x-zoomoutbtn.w;
21295 zoomoutbtn.y = compactbtn.y;
21296 zoomoutbtn.h = compactbtn.h;
21297
21298 for(int32_t i=0; i<=8; i++)
21299 {
21300 map_page_bar[i].x = mapscreen_x+(i*16*2*mapscreen_screenunit_scale);
21301 map_page_bar[i].y = mapscreen_y+((13)*16*mapscreen_screenunit_scale);
21302 map_page_bar[i].w = 64;
21303 map_page_bar[i].h = text_height(guifont)+12;
21304 }
21305
21306 minimap.w=7+48*3;
21307 minimap.h=16+27*3;
21308
21309 layer_panel.x=map_page_bar[0].x;
21310 layer_panel.y=map_page_bar[0].y+map_page_bar[0].h;
21311 layer_panel.w=map_page_bar[8].x+map_page_bar[8].w;
21312 layer_panel.h=text_height(guifont)+8;
21313 layerpanel_buttonwidth = 58;
21314 layerpanel_buttonheight = layer_panel.h;
21315 layerpanel_checkbox_hei = layerpanel_buttonheight-4;
21316 layerpanel_checkbox_wid = 14;
21317
21318 commands_list.w=4;
21319 commands_window.w=commands_list.w*commands_list.xscale+16;
21320 commands_window.x=combolist_window.x-commands_window.w;
21321 commands_window.y=layer_panel.y+layer_panel.h;
21322 commands_window.h=zq_screen_h-commands_window.y;
21323
21324 //buttons panel
21325 main_panel.x = 0;
21326 main_panel.y = layer_panel.y+layer_panel.h;
21327 main_panel.w = commands_window.x - main_panel.x;
21328 main_panel.h = zq_screen_h - main_panel.y;
21329 preview_panel = main_panel;
21330
21331 preview_text.x = preview_panel.x+3;
21332 preview_text.y = preview_panel.y+3;
21333 preview_text.w = 1;
21334 preview_text.h = 12;
21335 preview_text.xscale = 10;
21336 preview_text.yscale = text_height(get_zc_font(font_lfont_l));
21337
21338 minimap.x=3;
21339 minimap.y=main_panel.y+4;
21340
21341 real_minimap.x = minimap.x+3;
21342 real_minimap.y = minimap.y+5;
21343 real_minimap.w = 16;
21344 real_minimap.h = 9;
21345 real_minimap.xscale = 9;
21346 real_minimap.yscale = 9;
21347 real_minimap.fw = real_minimap.xscale*8;
21348 real_minimap.fh = real_minimap.yscale*8;
21349
21350 int upscale_mm = 4;
21351 int xwid = real_minimap.tw()*(upscale_mm-1);
21352 int xhei = real_minimap.th()*(upscale_mm-1);
21353 int zh = minimap.h+xhei+4;
21354 minimap_zoomed.set(minimap.x, zq_screen_h-zh, minimap.w+xwid, zh);
21355 real_minimap_zoomed.set(minimap_zoomed.x+3, minimap_zoomed.y+5, real_minimap.w, real_minimap.h, real_minimap.xscale*upscale_mm, real_minimap.yscale*upscale_mm);
21356 real_minimap_zoomed.fw = real_minimap_zoomed.xscale*8;
21357 real_minimap_zoomed.fh = real_minimap_zoomed.yscale*8;
21358
21359 screrrorpos.x = 575;
21360 screrrorpos.y = 388;
21361
21362 mouse_scroll_h=10;
21363
21364 favorites_list.x=favorites_window.x+8;
21365 favorites_list.y=favorites_window.y+16;
21366 favorites_list.xscale = 16;
21367 favorites_list.yscale = 16;
21368 favorites_list.w=(favorites_window.w-16)/favorites_list.xscale;
21369 favorites_list.h=(favorites_window.h-24)/favorites_list.yscale;
21370
21371 int bh = 16;
21372 int by = commands_window.y+4;
21373 commands_list.y=by+bh;
21374 commands_list.h=(zq_screen_h - commands_list.y) / commands_list.yscale;
21375 commands_list.x=commands_window.x+8;
21376
21377 commands_x.w = 20;
21378 commands_x.h = bh;
21379 commands_x.x = commands_list.x + commands_list.tw() - commands_x.w;
21380 commands_x.y = by;
21381
21382 commands_infobtn.w = 20;
21383 commands_infobtn.h = bh;
21384 commands_infobtn.x = commands_x.x - commands_infobtn.w;
21385 commands_infobtn.y = by;
21386
21387 commands_zoombtn.w = 20;
21388 commands_zoombtn.h = bh;
21389 commands_zoombtn.x = commands_infobtn.x - commands_zoombtn.w;
21390 commands_zoombtn.y = by;
21391
21392 commands_txt.x = commands_list.x;
21393 commands_txt.y = by+(bh-text_height(get_zc_font(font_lfont_l)))/2;
21394
21395 favorites_x.x = favorites_window.x + favorites_window.w - favorites_x.w - 2;
21396 favorites_x.y = favorites_list.y-15;
21397
21398 favorites_infobtn.x = favorites_x.x - favorites_infobtn.w;
21399 favorites_infobtn.y = favorites_x.y;
21400
21401 favorites_zoombtn.x = favorites_infobtn.x - favorites_zoombtn.w;
21402 favorites_zoombtn.y = favorites_infobtn.y;
21403
21404 favorites_pgright.x = favorites_zoombtn.x - favorites_pgright.w;
21405 favorites_pgright.y = favorites_zoombtn.y;
21406
21407 favorites_pgleft.x = favorites_pgright.x - favorites_pgleft.w;
21408 favorites_pgleft.y = favorites_pgleft.y;
21409
21410 txtoffs_single.x = 22;
21411 txtoffs_single.y = 6;
21412 txtoffs_double_1.x = 22;
21413 txtoffs_double_1.y = 2;
21414 txtoffs_double_2.x = 22;
21415 txtoffs_double_2.y = 10;
21416 panel_align = 0;
21417
21418 int sqx = minimap.x+minimap.tw();
21419 squares_panel.set(sqx,main_panel.y,main_panel.tw()-sqx,main_panel.th());
21420 int x2 = sqx+4;
21421 int x1 = x2 - (20+(8*3)+2);
21422 int y1 = main_panel.y+10;
21423 int sw = 20, sh = 20;
21424 int offs = sh+4;
21425
21426 itemsqr_pos.set(x2,y1+(0*offs),sw,sh);
21427 flagsqr_pos.set(x2,y1+(1*offs),sw,sh);
21428 stairsqr_pos.set(x2,y1+(2*offs),sw,sh);
21429 warparrival_pos.set(x2,y1+(6*offs),sw,sh);
21430
21431 enemy_prev_pos.x = main_panel.x+14;
21432 enemy_prev_pos.y = main_panel.y+12 + minimap.h;
21433 enemy_prev_pos.w = 4;
21434 enemy_prev_pos.h = 3;
21435 enemy_prev_pos.xscale = 16;
21436 enemy_prev_pos.yscale = 16;
21437 enemy_prev_pos.fw = enemy_prev_pos.xscale*2;
21438 enemy_prev_pos.fh = enemy_prev_pos.yscale*2;
21439
21440 warpret_pos[0].set(x1,y1+(4*offs),sw,sh);
21441 warpret_pos[1].set(x1,y1+(5*offs),sw,sh);
21442 warpret_pos[2].set(x2,y1+(4*offs),sw,sh);
21443 warpret_pos[3].set(x2,y1+(5*offs),sw,sh);
21444
21445 auto& last_alias_list = comboaliaslist[num_combo_cols-1];
21446 combopool_preview.x=comboaliaslist[0].x;
21447 combopool_preview.y=last_alias_list.y+(last_alias_list.h*last_alias_list.yscale)+16;
21448 combopool_preview.w=(last_alias_list.x+(last_alias_list.w*last_alias_list.xscale))-comboaliaslist[0].x;
21449 combopool_preview.h=(favorites_window.y-combopool_preview.y);//+favorites_window.h-10;
21450 combopool_preview.w -= combopool_preview.w%16;
21451 combopool_preview.h -= combopool_preview.h%16;
21452
21453 FONT* tfont = get_zc_font(font_lfont_l);
21454 combopool_prevbtn.w = text_length(tfont, "Unweighted")+10;
21455 combopool_prevbtn.h = 11;
21456 combopool_prevbtn.x = combopool_preview.x;
21457 combopool_prevbtn.y = combopool_preview.y-combopool_prevbtn.h;
21458
21459 mappage_count = 9;
21460
21461 txfont = get_zc_font(font_lfont_l);
21462 combo_preview_text1.set(combo_preview.x-9,combo_preview.y,1,3,1,text_height(txfont));
21463 combo_preview_text2.set(combo_preview2.x+combo_preview2.w+8,combo_preview2.y,1,3,1,text_height(txfont));
21464
21465 favorites_x.w = 30;
21466 favorites_infobtn.w = 30;
21467 favorites_zoombtn.w = 30;
21468 favorites_pgleft.w = 30;
21469 favorites_pgright.w = 30;
21470 }
21471 //Same in all modes
21472 {
21473
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(is_compact ? compact_zoomed_cmd : large_zoomed_cmd)
21474 {
21475 1 commands_list.w /= 2;
21476 1 commands_list.xscale *= 2;
21477 1 }
21478
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(is_compact ? compact_zoomed_fav : large_zoomed_fav)
21479 {
21480
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(favorites_list.w%2)
21481 favorites_list.x += (favorites_list.xscale / 2);
21482 1 favorites_list.xscale *= 2;
21483 1 favorites_list.yscale *= 2;
21484 1 favorites_list.w /= 2;
21485 1 favorites_list.h /= 2;
21486 1 }
21487
21488 1 favorites_x.h = 14;
21489 1 favorites_x.x = favorites_window.x + favorites_window.w - favorites_x.w - 2;
21490 1 favorites_x.y = favorites_list.y-15;
21491
21492 1 favorites_infobtn.h = favorites_x.h;
21493 1 favorites_infobtn.x = favorites_x.x - favorites_infobtn.w;
21494 1 favorites_infobtn.y = favorites_x.y;
21495
21496 1 favorites_zoombtn.h = favorites_infobtn.h;
21497 1 favorites_zoombtn.x = favorites_infobtn.x - favorites_zoombtn.w;
21498 1 favorites_zoombtn.y = favorites_infobtn.y;
21499
21500 1 favorites_pgright.h = favorites_zoombtn.h;
21501 1 favorites_pgright.x = favorites_zoombtn.x - favorites_pgright.w;
21502 1 favorites_pgright.y = favorites_zoombtn.y;
21503
21504 1 favorites_pgleft.h = favorites_pgright.h;
21505 1 favorites_pgleft.x = favorites_pgright.x - favorites_pgleft.w;
21506 1 favorites_pgleft.y = favorites_pgright.y;
21507
21508 1 mainbar.x = dialogs[0].x+dialogs[0].w;
21509 1 mainbar.y = 0;
21510 1 mainbar.w = zoomoutbtn.x-mainbar.x;
21511 1 mainbar.h = drawmode_btn.h;
21512 }
21513
21514 //Ensure current combo list selected is valid
21515 1 current_combolist=vbound(current_combolist,0,num_combo_cols-1);
21516 1 current_comboalist=vbound(current_comboalist,0,num_combo_cols-1);
21517 1 current_cpoollist=vbound(current_cpoollist,0,num_combo_cols-1);
21518 1 current_cautolist = vbound(current_cautolist, 0, num_combo_cols - 1);
21519
21520 //Generate bitmaps
21521 1 init_bitmap(&mapscreenbmp,16*(showedges?18:16),16*(showedges?13:11));
21522 1 init_bitmap(&brushbmp,256*mapscreen_screenunit_scale,176*mapscreen_screenunit_scale);
21523 1 init_bitmap(&brushscreen,(256+(showedges?16:0))*mapscreen_screenunit_scale,(176+(showedges?16:0))*mapscreen_screenunit_scale);
21524
21525 1 init_bitmap(&screen2,zq_screen_w,zq_screen_h);
21526
21527 1 center_zq_class_dialogs();
21528 1 center_zq_files_dialogs();
21529 1 center_zq_subscreen_dialogs();
21530 1 center_zq_tiles_dialogs();
21531 1 center_zquest_dialogs();
21532
21533 1 aspect_ratio = zq_screen_h / double(zq_screen_w);
21534
21535 1 mmap_init();
21536 1 }
21537
21538 11 void remove_locked_params_on_exit()
21539 {
21540 11 al_trace("Removing timers. \n");
21541 11 remove_int(fps_callback);
21542 11 remove_int(dclick_check);
21543 11 }
21544
21545 11 void destroy_bitmaps_on_exit()
21546 {
21547 11 al_trace("Cleaning bitmaps...");
21548 11 destroy_bitmap(screen2);
21549 11 destroy_bitmap(mapscreenbmp);
21550 11 destroy_bitmap(dmapbmp_small);
21551 11 destroy_bitmap(dmapbmp_large);
21552 11 destroy_bitmap(brushbmp);
21553 11 destroy_bitmap(brushscreen);
21554 11 al_trace("...");
21555
21556
2/2
✓ Branch 0 taken 528 times.
✓ Branch 1 taken 11 times.
539 for(int32_t i=0; i<MOUSE_BMP_MAX*4; i++)
21557 {
21558 528 destroy_bitmap(mouse_bmp[i/4][i%4]);
21559 528 destroy_bitmap(mouse_bmp_1x[i/4][i%4]);
21560 528 }
21561
21562
2/2
✓ Branch 0 taken 352 times.
✓ Branch 1 taken 11 times.
363 for(int32_t i=0; i<ICON_BMP_MAX*4; i++)
21563 352 destroy_bitmap(icon_bmp[i/4][i%4]);
21564
21565
2/2
✓ Branch 0 taken 704 times.
✓ Branch 1 taken 11 times.
715 for(int32_t i=0; i<16*4; i++)
21566 704 destroy_bitmap(flag_bmp[i/4][i%4]);
21567
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 11 times.
33 for(int32_t i=0; i<2; i++)
21568 22 destroy_bitmap(select_bmp[i]);
21569
21570
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 11 times.
99 for(int32_t i=0; i<MAXARROWS; i++)
21571 88 destroy_bitmap(arrow_bmp[i]);
21572
21573 11 al_trace(" OK. \n");
21574 11 }
21575
21576
21577 11 void quit_game()
21578 {
21579 11 set_last_timed_save(nullptr);
21580 11 save_config_file();
21581 11 zc_set_palette(black_palette);
21582 11 zc_stop_midi();
21583
21584 11 remove_locked_params_on_exit();
21585
21586 11 al_trace("Cleaning sfx. \n");
21587
21588
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<WAV_COUNT; i++)
21589 {
21590
2/2
✓ Branch 0 taken 2805 times.
✓ Branch 1 taken 11 times.
2816 if(customsfxdata[i].data!=NULL)
21591 {
21592 // delete [] customsfxdata[i].data;
21593 2805 free(customsfxdata[i].data);
21594 2805 }
21595
21596
1/2
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
2816 delete [] sfx_string[i];
21597 2816 }
21598
21599
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<MAXWPNS; i++)
21600 {
21601
1/2
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
2816 delete [] weapon_string[i];
21602 2816 }
21603
21604
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<MAXITEMS; i++)
21605 {
21606
1/2
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
2816 delete [] item_string[i];
21607 2816 }
21608
21609
2/2
✓ Branch 0 taken 5632 times.
✓ Branch 1 taken 11 times.
5643 for(int32_t i=0; i<eMAXGUYS; i++)
21610 {
21611
1/2
✓ Branch 0 taken 5632 times.
✗ Branch 1 not taken.
5632 delete [] guy_string[i];
21612 5632 }
21613
21614 11 al_trace("Cleaning script buffer. \n");
21615
21616
2/2
✓ Branch 0 taken 5632 times.
✓ Branch 1 taken 11 times.
5643 for(int32_t i=0; i<NUMSCRIPTFFC; i++)
21617 {
21618
2/4
✓ Branch 0 taken 5632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5632 times.
5632 if(ffscripts[i]!=NULL) delete ffscripts[i];
21619 5632 }
21620
21621
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTITEM; i++)
21622 {
21623
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(itemscripts[i]!=NULL) delete itemscripts[i];
21624 2816 }
21625
21626
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTGUYS; i++)
21627 {
21628
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(guyscripts[i]!=NULL) delete guyscripts[i];
21629 2816 }
21630
21631
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
21632 {
21633
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(lwpnscripts[i]!=NULL) delete lwpnscripts[i];
21634 2816 }
21635
21636
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
21637 {
21638
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(ewpnscripts[i]!=NULL) delete ewpnscripts[i];
21639 2816 }
21640
21641
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTSCREEN; i++)
21642 {
21643
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(screenscripts[i]!=NULL) delete screenscripts[i];
21644 2816 }
21645
21646
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 11 times.
44 for(int32_t i=0; i<3; i++) //should this be NUMSCRIPTGLOBAL or NUMSCRIPTGLOBALOLD? -Z
21647 {
21648
2/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
33 if(globalscripts[i]!=NULL) delete globalscripts[i];
21649 33 }
21650
21651
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 11 times.
66 for(int32_t i=0; i<NUMSCRIPTHERO; i++)
21652 {
21653
2/4
✓ Branch 0 taken 55 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55 times.
55 if(playerscripts[i]!=NULL) delete playerscripts[i];
21654 55 }
21655
21656
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTSDMAP; i++)
21657 {
21658
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(dmapscripts[i]!=NULL) delete dmapscripts[i];
21659 2816 }
21660
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTSITEMSPRITE; i++)
21661 {
21662
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(itemspritescripts[i]!=NULL) delete itemspritescripts[i];
21663 2816 }
21664
2/2
✓ Branch 0 taken 5632 times.
✓ Branch 1 taken 11 times.
5643 for(int32_t i=0; i<NUMSCRIPTSCOMBODATA; i++)
21665 {
21666
2/4
✓ Branch 0 taken 5632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5632 times.
5632 if(comboscripts[i]!=NULL) delete comboscripts[i];
21667 5632 }
21668
2/2
✓ Branch 0 taken 2816 times.
✓ Branch 1 taken 11 times.
2827 for(int32_t i=0; i<NUMSCRIPTSSUBSCREEN; i++)
21669 {
21670
2/4
✓ Branch 0 taken 2816 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2816 times.
2816 if(subscreenscripts[i]!=NULL) delete subscreenscripts[i];
21671 2816 }
21672
21673 11 al_trace("Cleaning qst buffers. \n");
21674 11 del_qst_buffers();
21675
21676
21677 11 al_trace("Cleaning midis. \n");
21678
21679
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 5632 times.
5643 for(uint q = 0; q < MAXCUSTOMMIDIS; ++q)
21680 5632 customtunes[q].reset();
21681
21682 11 al_trace("Cleaning undotilebuf. \n");
21683
21684 11 undocombobuf.clear();
21685
21686
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(newundotilebuf)
21687 {
21688
2/2
✓ Branch 0 taken 2359500 times.
✓ Branch 1 taken 11 times.
2359511 for(int32_t i=0; i<NEWMAXTILES; i++)
21689
1/2
✓ Branch 0 taken 2359500 times.
✗ Branch 1 not taken.
2359500 if(newundotilebuf[i].data) free(newundotilebuf[i].data);
21690
21691 11 free(newundotilebuf);
21692 11 }
21693
21694
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(filepath) free(filepath);
21695
21696
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(datapath) free(datapath);
21697
21698
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(midipath) free(midipath);
21699
21700
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(imagepath) free(imagepath);
21701
21702
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(tmusicpath) free(tmusicpath);
21703
21704
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if(last_timed_save) free(last_timed_save);
21705
21706 11 destroy_bitmaps_on_exit();
21707 11 }
21708
21709 void quit_game2()
21710 {
21711 set_last_timed_save(nullptr);
21712 save_config_file();
21713 zc_set_palette(black_palette);
21714 zc_stop_midi();
21715
21716 remove_locked_params_on_exit();
21717
21718 al_trace("Cleaning sfx. \n");
21719
21720 for(int32_t i=0; i<WAV_COUNT; i++)
21721 {
21722 if(customsfxdata[i].data!=NULL)
21723 {
21724 // delete [] customsfxdata[i].data;
21725 free(customsfxdata[i].data);
21726 }
21727
21728 delete [] sfx_string[i];
21729 }
21730
21731 for(int32_t i=0; i<MAXWPNS; i++)
21732 {
21733 delete [] weapon_string[i];
21734 }
21735
21736 for(int32_t i=0; i<MAXITEMS; i++)
21737 {
21738 delete [] item_string[i];
21739 }
21740
21741 for(int32_t i=0; i<eMAXGUYS; i++)
21742 {
21743 delete [] guy_string[i];
21744 }
21745
21746 al_trace("Cleaning script buffer. \n");
21747
21748 for(int32_t i=0; i<NUMSCRIPTFFC; i++)
21749 {
21750 if(ffscripts[i]!=NULL) delete ffscripts[i];
21751 }
21752
21753 for(int32_t i=0; i<NUMSCRIPTITEM; i++)
21754 {
21755 if(itemscripts[i]!=NULL) delete itemscripts[i];
21756 }
21757
21758 for(int32_t i=0; i<NUMSCRIPTGUYS; i++)
21759 {
21760 if(guyscripts[i]!=NULL) delete guyscripts[i];
21761 }
21762
21763 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
21764 {
21765 if(lwpnscripts[i]!=NULL) delete lwpnscripts[i];
21766 }
21767
21768 for(int32_t i=0; i<NUMSCRIPTWEAPONS; i++)
21769 {
21770 if(ewpnscripts[i]!=NULL) delete ewpnscripts[i];
21771 }
21772
21773 for(int32_t i=0; i<NUMSCRIPTSCREEN; i++)
21774 {
21775 if(screenscripts[i]!=NULL) delete screenscripts[i];
21776 }
21777
21778 for(int32_t i=0; i<3; i++) //should this be NUMSCRIPTGLOBAL or NUMSCRIPTGLOBALOLD? -Z
21779 {
21780 if(globalscripts[i]!=NULL) delete globalscripts[i];
21781 }
21782
21783 for(int32_t i=0; i<NUMSCRIPTHERO; i++)
21784 {
21785 if(playerscripts[i]!=NULL) delete playerscripts[i];
21786 }
21787
21788 for(int32_t i=0; i<NUMSCRIPTSDMAP; i++)
21789 {
21790 if(dmapscripts[i]!=NULL) delete dmapscripts[i];
21791 }
21792 for(int32_t i=0; i<NUMSCRIPTSITEMSPRITE; i++)
21793 {
21794 if(itemspritescripts[i]!=NULL) delete itemspritescripts[i];
21795 }
21796 for(int32_t i=0; i<NUMSCRIPTSCOMBODATA; i++)
21797 {
21798 if(comboscripts[i]!=NULL) delete comboscripts[i];
21799 }
21800 for(int32_t i=0; i<NUMSCRIPTSSUBSCREEN; i++)
21801 {
21802 if(subscreenscripts[i]!=NULL) delete subscreenscripts[i];
21803 }
21804
21805 al_trace("Cleaning qst buffers. \n");
21806 del_qst_buffers();
21807
21808
21809 al_trace("Cleaning midis. \n");
21810
21811 for(uint q = 0; q < MAXCUSTOMMIDIS; ++q)
21812 customtunes[q].reset();
21813
21814 al_trace("Cleaning undotilebuf. \n");
21815
21816 undocombobuf.clear();
21817
21818 if(newundotilebuf)
21819 {
21820 for(int32_t i=0; i<NEWMAXTILES; i++)
21821 if(newundotilebuf[i].data) free(newundotilebuf[i].data);
21822
21823 free(newundotilebuf);
21824 }
21825
21826 if(filepath) free(filepath);
21827
21828 if(datapath) free(datapath);
21829
21830 if(midipath) free(midipath);
21831
21832 if(imagepath) free(imagepath);
21833
21834 if(tmusicpath) free(tmusicpath);
21835
21836 if(last_timed_save) free(last_timed_save);
21837 }
21838
21839 1 void center_zquest_dialogs()
21840 {
21841 1 jwin_center_dialog(assignscript_dlg);
21842 1 center_zq_cset_dialogs();
21843 1 jwin_center_dialog(change_track_dlg);
21844 1 jwin_center_dialog(csetfix_dlg);
21845 1 center_zq_door_dialogs();
21846 1 jwin_center_dialog(editcomboa_dlg);
21847 1 jwin_center_dialog(editinfo_dlg);
21848 1 jwin_center_dialog(editshop_dlg);
21849 1 jwin_center_dialog(list_dlg);
21850 1 jwin_center_dialog(loadmap_dlg);
21851 1 jwin_center_dialog(misccolors_dlg);
21852 1 jwin_center_dialog(newcomboa_dlg);
21853 1 jwin_center_dialog(orgcomboa_dlg);
21854 1 jwin_center_dialog(path_dlg);
21855 1 jwin_center_dialog(screen_pal_dlg);
21856 1 jwin_center_dialog(secret_dlg);
21857 1 jwin_center_dialog(showpal_dlg);
21858 1 jwin_center_dialog(strlist_dlg);
21859 1 jwin_center_dialog(template_dlg);
21860 1 jwin_center_dialog(tp_dlg);
21861 1 jwin_center_dialog(tilewarp_dlg);
21862 1 jwin_center_dialog(sidewarp_dlg);
21863 1 jwin_center_dialog(warpring_dlg);
21864 1 center_zscript_dialogs();
21865 1 }
21866
21867
21868 void animate_coords()
21869 {
21870 coord_frame=(coord_timer>>3)&3;
21871
21872 if(++coord_timer>=(1<<5))
21873 {
21874 coord_timer=0;
21875 }
21876 }
21877
21878 static const char *help_list[] =
21879 {
21880 "PREVIEW MODE",
21881 "PgUp/PgDn - Scroll through hotkey list",
21882 "Esc/Enter - Exit Preview Mode",
21883 "R - Restore screen to original state",
21884 "C - Toggle combo cycling On/Off",
21885 "S - Trigger screen secrets",
21886 "Q/W/F - These still work",
21887 "P - Pause everything",
21888 "A - Advance frame-by-frame",
21889 "1-4 - Trigger tile warp A-D",
21890 "5-8 - Trigger side warp A-D",
21891 "9 - Enable timed warps",
21892 "",
21893 "",
21894 };
21895
21896 void do_previewtext()
21897 {
21898 FONT* oldfont = font;
21899 font = get_zc_font(font_lfont_l);
21900
21901 //Put in help areas
21902 auto& sqr = preview_text;
21903 int ind = 0, len = 0;
21904 for(int q = 0; q < 12; ++q)
21905 {
21906 int l = text_length(font, help_list[q]);
21907 if(len < l) len = l;
21908 }
21909 sqr.xscale = len+2;
21910 sqr.yscale = text_height(font);
21911 for(int col = 0; col < sqr.w; ++col)
21912 {
21913 for(int row = 0; row < sqr.h; ++row)
21914 {
21915 auto& line = sqr.subsquare(col,row);
21916 textprintf_ex(screen,font,line.x,line.y,jwin_pal[jcTEXTFG],-1,"%s",help_list[ind++]);
21917 }
21918 }
21919
21920 font = oldfont;
21921 }
21922
21923
21924 bool reload_fonts = false;
21925 void run_zq_frame()
21926 {
21927 if(reload_fonts)
21928 {
21929 init_custom_fonts();
21930 load_size_poses();
21931 reload_fonts = false;
21932 }
21933
21934 handlePreviewMode();
21935 domouse();
21936 get_screen_rti()->freeze = false;
21937 custom_vsync();
21938 refresh(rCLEAR|rALL);
21939 }
21940 1 int32_t d_nbmenu_proc(int32_t msg,DIALOG *d,int32_t c)
21941 {
21942
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 switch(msg)
21943 {
21944 case MSG_VSYNC:
21945 run_zq_frame();
21946 break;
21947 case MSG_GOTMOUSE:
21948 case MSG_XCHAR:
21949 ComboBrushPause=1;
21950 refresh(rMAP);
21951 ComboBrushPause=0;
21952 clear_tooltip();
21953 break;
21954 }
21955
21956 1 return GuiMenu::proc(msg,d,c);
21957 }
21958
21959 bool prv_press=false;
21960
21961 void dopreview()
21962 {
21963 refresh(rMAP);
21964
21965 while(!(gui_mouse_b()))
21966 {
21967 if(keypressed())
21968 {
21969 if(!prv_press)
21970 {
21971 prv_press=true;
21972
21973 switch(readkey()>>8)
21974 {
21975 case KEY_ESC:
21976 case KEY_ENTER:
21977 case KEY_ENTER_PAD:
21978 goto finished;
21979 break;
21980
21981 case KEY_F:
21982 Flags^=cFLAGS;
21983 refresh(rMAP);
21984 break;
21985
21986 case KEY_R:
21987 onReloadPreview();
21988 break;
21989
21990 case KEY_S:
21991 onSecretsPreview();
21992 break;
21993
21994 case KEY_C:
21995 onCopy();
21996 break;
21997
21998 case KEY_A:
21999 onAKey();
22000 break;
22001
22002 case KEY_P:
22003 onP();
22004 break;
22005
22006 case KEY_L:
22007 onShowDarkness();
22008 break;
22009
22010 case KEY_1:
22011 Map.prv_dowarp(0,0);
22012 prv_warp=0;
22013 break;
22014
22015 case KEY_2:
22016 Map.prv_dowarp(0,1);
22017 prv_warp=0;
22018 break;
22019
22020 case KEY_3:
22021 Map.prv_dowarp(0,2);
22022 prv_warp=0;
22023 break;
22024
22025 case KEY_4:
22026 Map.prv_dowarp(0,3);
22027 prv_warp=0;
22028 break;
22029
22030 case KEY_5:
22031 Map.prv_dowarp(1,0);
22032 prv_warp=0;
22033 break;
22034
22035 case KEY_6:
22036 Map.prv_dowarp(1,1);
22037 prv_warp=0;
22038 break;
22039
22040 case KEY_7:
22041 Map.prv_dowarp(1,2);
22042 prv_warp=0;
22043 break;
22044
22045 case KEY_8:
22046 Map.prv_dowarp(1,3);
22047 prv_warp=0;
22048 break;
22049
22050 case KEY_9:
22051 if(prv_twon)
22052 {
22053 prv_twon=0;
22054 Map.set_prvtime(0);
22055 prv_warp=0;
22056 }
22057 else
22058 {
22059 Map.set_prvtime(Map.get_prvscr()->timedwarptics);
22060 prv_twon=1;
22061 }
22062
22063 break;
22064
22065 case KEY_W:
22066 onShowWalkability();
22067 break;
22068
22069 case KEY_Q:
22070 onShowComboInfoCSet();
22071 break;
22072 }
22073 }
22074 else
22075 {
22076 readkey();
22077 }
22078 }
22079 else
22080 {
22081 prv_press=false;
22082 }
22083
22084 if(prv_warp)
22085 {
22086 Map.prv_dowarp(1,0);
22087 prv_warp=0;
22088 }
22089
22090 if(Map.get_prvfreeze())
22091 {
22092 if(Map.get_prvadvance())
22093 {
22094 custom_vsync();
22095 Map.set_prvadvance(0);
22096 }
22097 }
22098 else
22099 {
22100 custom_vsync();
22101 Map.set_prvadvance(0);
22102 }
22103
22104 refresh(rALL);
22105 }
22106
22107 finished:
22108 //Flags=of;
22109 reset_combo_animations();
22110 reset_combo_animations2();
22111 MouseSprite::set(ZQM_NORMAL);
22112 prv_mode=0;
22113 prv_warp=0;
22114 Map.end_prv();
22115 Map.refresh_color();
22116 refresh(rMAP+rMENU);
22117
22118 while(gui_mouse_b())
22119 {
22120 /* do nothing */
22121 rest(1);
22122 }
22123 }
22124
22125 void call_vidmode_dlg();
22126 int32_t onZQVidMode()
22127 {
22128 call_vidmode_dlg();
22129 return D_O_K;
22130 }
22131
22132 bool screenIsScrolling()
22133 {
22134 return false;
22135 }
22136
22137 void write_includepaths()
22138 {
22139 FILE* f = fopen("includepaths.txt", "w");
22140 if(f)
22141 {
22142 fwrite(FFCore.includePathString,1,strlen(FFCore.includePathString),f);
22143 fclose(f);
22144 }
22145 }
22146
22147 11 int32_t save_config_file()
22148 {
22149
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (!application_has_loaded) return 0;
22150
22151 char qtnametitle[20];
22152 char qtpathtitle[20];
22153 char *datapath2=(char *)malloc(2048);
22154 char *midipath2=(char *)malloc(2048);
22155 char *imagepath2=(char *)malloc(2048);
22156 char *tmusicpath2=(char *)malloc(2048);
22157 strcpy(datapath2, datapath);
22158 strcpy(midipath2, midipath);
22159 strcpy(imagepath2, imagepath);
22160 strcpy(tmusicpath2, tmusicpath);
22161 chop_path(datapath2);
22162 chop_path(midipath2);
22163 chop_path(imagepath2);
22164 chop_path(tmusicpath2);
22165 write_includepaths();
22166
22167 zc_set_config("zquest",data_path_name,datapath2);
22168 zc_set_config("zquest",midi_path_name,midipath2);
22169 zc_set_config("zquest",image_path_name,imagepath2);
22170 zc_set_config("zquest",tmusic_path_name,tmusicpath2);
22171
22172 if (all_get_display() && !all_get_fullscreen_flag() && SaveDragResize)
22173 {
22174 window_width = al_get_display_width(all_get_display());
22175 window_height = al_get_display_height(all_get_display());
22176 zc_set_config("zquest","window_width",window_width);
22177 zc_set_config("zquest","window_height",window_height);
22178 }
22179 if (all_get_display() && !all_get_fullscreen_flag() && SaveWinPos)
22180 {
22181 int o_window_x, o_window_y;
22182 al_get_window_position(all_get_display(), &o_window_x, &o_window_y);
22183 zc_set_config("zquest", "window_x", o_window_x);
22184 zc_set_config("zquest", "window_y", o_window_y);
22185 }
22186
22187 byte b = 0;
22188 for(int32_t x=0; x<7; x++)
22189 {
22190 set_bit(&b,x,LayerMaskInt[x]);
22191 }
22192
22193 zc_set_config("zquest","layer_mask",b);
22194
22195 flush_config_file();
22196 #ifdef __EMSCRIPTEN__
22197 em_sync_fs();
22198 #endif
22199 free(datapath2);
22200 free(midipath2);
22201 free(imagepath2);
22202 free(tmusicpath2);
22203 return 0;
22204 11 }
22205
22206 int32_t d_timer_proc(int32_t msg, DIALOG *d, int32_t c)
22207 {
22208 //these are here to bypass compiler warnings about unused arguments
22209 c=c;
22210 d=d;
22211
22212 switch(msg)
22213 {
22214 case MSG_IDLE:
22215 #ifdef _WIN32
22216 if(zqUseWin32Proc != FALSE)
22217 win32data.Update(Frameskip); //experimental win32 fixes
22218
22219 #endif
22220
22221 // This has been crashing on Windows, and it saves plenty without it
22222 //check_autosave();
22223 break;
22224 }
22225
22226 return D_O_K;
22227 }
22228
22229 void check_autosave()
22230 {
22231 if (!first_save)
22232 return;
22233
22234 if(AutoSaveInterval>0)
22235 {
22236 time(&auto_save_time_current);
22237 auto_save_time_diff = difftime(auto_save_time_current,auto_save_time_start);
22238
22239 if(auto_save_time_diff>AutoSaveInterval*60)
22240 {
22241 if (!autosaved)
22242 {
22243 MouseSprite::set(ZQM_NORMAL);
22244 replace_extension(last_timed_save, filepath, "qt0", 2047);
22245 set_last_timed_save(last_timed_save);
22246
22247 if((header.zelda_version != ZELDA_VERSION || header.build != VERSION_BUILD))
22248 {
22249 displayinfo("Auto Save","This quest was saved in an older version of ZQuest.\nIf you wish to use the autosave feature, you must manually save the files in this version first.");
22250 time(&auto_save_time_start);
22251 return;
22252 }
22253
22254 int32_t ret = save_quest(last_timed_save, true);
22255
22256 if(ret)
22257 {
22258 displayinfo("Error","Timed save did not complete successfully.");
22259 set_last_timed_save(nullptr);
22260 }
22261 else autosaved = true;
22262
22263 save_config_file();
22264 }
22265 time(&auto_save_time_start);
22266 }
22267 }
22268 }
22269
22270 void flushItemCache(bool) {}
22271 void ringcolor(bool forceDefault)
22272 {
22273 forceDefault=forceDefault;
22274 }
22275
22276 bool item_disabled(int32_t)
22277 {
22278 return false;
22279 }
22280
22281 int32_t onCmdExit()
22282 {
22283 // replaces onExit for the -large button command "Exit"
22284 close_button_quit = true;
22285 return 0;
22286 }
22287
22288 int32_t onQuickCompile()
22289 {
22290 if(do_compile_and_slots(1,false))
22291 {
22292 mark_save_dirty();
22293 InfoDialog("Quick Compile","Success!").show();
22294 }
22295 else
22296 {
22297 InfoDialog("Quick Compile","Failure!").show();
22298 }
22299 return 0;
22300 }
22301 int32_t onSmartCompile()
22302 {
22303 if(do_compile_and_slots(2,false))
22304 {
22305 mark_save_dirty();
22306 InfoDialog("Smart Compile","Success!").show();
22307 }
22308 else
22309 {
22310 InfoDialog("Smart Compile","Failure!").show();
22311 }
22312 return 0;
22313 }
22314
22315 int32_t strchrnum(char const* str, char c)
22316 {
22317 for(int32_t i=0; str[i]; ++i)
22318 {
22319 if(str[i]==c)
22320 {
22321 return i;
22322 }
22323 }
22324
22325 return -1;
22326 }
22327
22328 int32_t get_longest_line_length(FONT *f, char* str)
22329 {
22330 int32_t maxlen=0;
22331 char* tmpstr = str;
22332 char temp=0;
22333 int32_t t=0;
22334 int32_t new_t=-1;
22335 while(tmpstr[0])
22336 {
22337 t=strchrnum(tmpstr, '\n');
22338
22339 if(t==-1)
22340 {
22341 t=(int32_t)strlen(tmpstr);
22342 }
22343
22344 if((uint32_t)t!=strlen(tmpstr))
22345 {
22346 new_t=t+1;
22347 }
22348 else
22349 {
22350 new_t=-1;
22351 }
22352
22353 temp = tmpstr[t];
22354 tmpstr[t]=0;
22355 maxlen=zc_max(maxlen,text_length(f, tmpstr));
22356 tmpstr[t]=temp;
22357
22358 if(new_t!=-1)
22359 {
22360 tmpstr+=new_t;
22361 }
22362 else break;
22363 }
22364 return maxlen;
22365 }
22366
22367 int32_t count_lines(char const* str)
22368 {
22369 int32_t count=1;
22370
22371 for(word i=0; i<strlen(str); ++i)
22372 {
22373 if(str[i]=='\n')
22374 {
22375 ++count;
22376 }
22377 }
22378
22379 return count;
22380 }
22381
22382 void textbox_out(BITMAP* dest, FONT* font, int x, int y, int fg, int bg, char const* str, int align, size_and_pos* dims)
22383 {
22384 static size_and_pos nilsz;
22385 size_and_pos& txbox = dims ? *dims : nilsz;
22386
22387 char* kill = (char*)malloc(strlen(str)+1);
22388 char *tmpstr = kill;
22389 strcpy(tmpstr,str);
22390
22391 while(tmpstr[0] == '\n')
22392 ++tmpstr;
22393 int len = strlen(tmpstr);
22394 while(tmpstr[len-1] == '\n')
22395 tmpstr[--len] = 0;
22396
22397 txbox.x=x;
22398 txbox.y=y;
22399 int32_t lines=count_lines(tmpstr);
22400 txbox.w = 1;
22401 txbox.h = lines;
22402 txbox.xscale = get_longest_line_length(font, tmpstr);
22403 txbox.yscale = text_height(font);
22404
22405 int ax = 0; //Aligned x
22406 switch(align)
22407 {
22408 case 0: //left
22409 break;
22410 case 1: //center
22411 txbox.x -= txbox.xscale/2;
22412 ax = txbox.xscale/2;
22413 break;
22414 case 2: //right
22415 txbox.x -= txbox.xscale;
22416 ax = txbox.xscale;
22417 break;
22418 }
22419
22420 int bw = txbox.w*txbox.xscale;
22421 int bh = txbox.h*txbox.yscale;
22422 BITMAP* outbmp = create_bitmap_ex(8, bw, bh);
22423 clear_to_color(outbmp, bg);
22424
22425 char temp = 0;
22426 int32_t t=0;
22427 int32_t new_t=-1;
22428 int32_t line=0;
22429
22430 while(tmpstr[t])
22431 {
22432 t=strchrnum(tmpstr, '\n');
22433
22434 if(t==-1)
22435 t=(int32_t)strlen(tmpstr);
22436
22437 if((uint32_t)t!=strlen(tmpstr))
22438 new_t=t+1;
22439 else
22440 new_t=-1;
22441
22442 temp = tmpstr[t];
22443 tmpstr[t]=0;
22444 gui_textout_ln(outbmp, font, (ucc*)tmpstr, ax, (line*txbox.yscale), fg, -1, align);
22445 tmpstr[t]=temp;
22446 ++line;
22447
22448 if(new_t!=-1)
22449 {
22450 tmpstr+=new_t;
22451 t=0;
22452 }
22453 }
22454
22455 blit(outbmp, dest, 0, 0, txbox.x, txbox.y, bw, bh);
22456 destroy_bitmap(outbmp);
22457 free(kill);
22458 }
22459
22460 void highlight_sqr(BITMAP* dest, int color, int x, int y, int w, int h, int thick)
22461 {
22462 for(int q = 0; q < thick; ++q)
22463 {
22464 safe_rect(dest, x+q, y+q, x+w-1-q, y+h-1-q, color);
22465 }
22466 }
22467 void highlight_sqr(BITMAP* dest, int color, size_and_pos const& rec, int thick)
22468 {
22469 highlight_sqr(dest, color, rec.x, rec.y, rec.tw(), rec.th(), thick);
22470 }
22471 void highlight_frag(BITMAP* dest, int color, int x1, int y1, int w, int h, int fw, int fh, int thick)
22472 {
22473 int xc = x1+fw-1;
22474 int yc = y1+fh-1;
22475 int x2 = x1+w-1;
22476 int y2 = y1+h-1;
22477
22478 hline(dest, x1, y1, x2, color);
22479 vline(dest, x1, y1, y2, color);
22480
22481 hline(dest, x1, y2, xc, color);
22482 vline(dest, x2, y1, yc, color);
22483 hline(dest, xc, yc, x2, color);
22484 vline(dest, xc, yc, y2, color);
22485 }
22486 void highlight_frag(BITMAP* dest, int color, size_and_pos const& rec, int thick)
22487 {
22488 highlight_frag(dest, color, rec.x, rec.y, rec.tw(), rec.th(), rec.fw, rec.fh, thick);
22489 }
22490
22491 void highlight(BITMAP* dest, size_and_pos& hl)
22492 {
22493 if(hl.fw > -1 && hl.fh > -1)
22494 {
22495 highlight_frag(dest, hl.data[1], hl, hl.data[0]);
22496 }
22497 else highlight_sqr(dest, hl.data[1], hl, hl.data[0]);
22498 }
22499
22500 std::pair<int, int> get_box_text_size(char const* tipmsg, double txscale)
22501 {
22502 if(txscale < 1) txscale = 1;
22503 char* kill = (char*)malloc(strlen(tipmsg)+1);
22504 char *tmpstr = kill;
22505 strcpy(tmpstr,tipmsg);
22506
22507 while(tmpstr[0] == '\n')
22508 ++tmpstr;
22509 int len = strlen(tmpstr);
22510 while(tmpstr[len-1] == '\n')
22511 tmpstr[--len] = 0;
22512
22513 int32_t lines = count_lines(tmpstr);
22514 int txlen = get_longest_line_length(font, tmpstr);
22515 int txhei = lines*text_height(font);
22516 int tx_sclen = (txlen * txscale);
22517 int tx_schei = (txhei * txscale);
22518 int w = tx_sclen + 8 + 1;
22519 int h = tx_schei + 8 + 1;
22520 if (w > zq_screen_w)
22521 w = zq_screen_w;
22522 if (h > zq_screen_h)
22523 h = zq_screen_h;
22524 return {w, h};
22525 }
22526
22527 void draw_box(BITMAP* destbmp, size_and_pos* pos, char const* tipmsg, double txscale)
22528 {
22529 if(txscale < 1) txscale = 1;
22530 char* kill = (char*)malloc(strlen(tipmsg)+1);
22531 char *tmpstr = kill;
22532 strcpy(tmpstr,tipmsg);
22533
22534 while(tmpstr[0] == '\n')
22535 ++tmpstr;
22536 int len = strlen(tmpstr);
22537 while(tmpstr[len-1] == '\n')
22538 tmpstr[--len] = 0;
22539
22540 auto& box = *pos;
22541 clear_bitmap(destbmp);
22542
22543 int32_t lines=count_lines(tmpstr);
22544 int txlen = get_longest_line_length(font, tmpstr);
22545 int txhei = lines*text_height(font);
22546 int tx_sclen = (txlen * txscale);
22547 int tx_schei = (txhei * txscale);
22548 box.w = tx_sclen + 8 + 1;
22549 box.h = tx_schei + 8 + 1;
22550 if (box.w > zq_screen_w)
22551 box.w = zq_screen_w;
22552 if (box.h > zq_screen_h)
22553 box.h = zq_screen_h;
22554
22555 if(box.x+box.w>=zq_screen_w)
22556 {
22557 box.x=(zq_screen_w - box.w);
22558 }
22559
22560 if(box.y+box.h>=zq_screen_h)
22561 {
22562 box.y=(zq_screen_h - box.h);
22563 }
22564
22565 rectfill(destbmp, 1, 1, box.w-3, box.h-3, jwin_pal[jcTEXTBG]);
22566 rect(destbmp, 0, 0, box.w-2, box.h-2, jwin_pal[jcTEXTFG]);
22567 vline(destbmp, box.w-1, 0, box.h-1, jwin_pal[jcTEXTFG]);
22568 hline(destbmp, 1, box.h-1, box.w-2, jwin_pal[jcTEXTFG]);
22569 destbmp->line[box.h-1][0]=0;
22570 destbmp->line[0][box.w-1]=0;
22571
22572 char temp = 0;
22573 int32_t t=0;
22574 int32_t new_t=-1;
22575 int32_t line=0;
22576
22577 BITMAP* txbmp = create_bitmap_ex(8,box.w,box.h);
22578 clear_bitmap(txbmp);
22579 while(tmpstr[t])
22580 {
22581 t=strchrnum(tmpstr, '\n');
22582
22583 if(t==-1)
22584 {
22585 t=(int32_t)strlen(tmpstr);
22586 }
22587
22588 if((uint32_t)t!=strlen(tmpstr))
22589 {
22590 new_t=t+1;
22591 }
22592 else
22593 {
22594 new_t=-1;
22595 }
22596
22597 temp = tmpstr[t];
22598 tmpstr[t]=0;
22599 textprintf_ex(txbmp, font, 0, (line*text_height(font)), jwin_pal[jcTEXTFG], -1, "%s", tmpstr);
22600 tmpstr[t]=temp;
22601 ++line;
22602
22603 if(new_t!=-1)
22604 {
22605 tmpstr+=new_t;
22606 t=0;
22607 }
22608 }
22609 masked_stretch_blit(txbmp,destbmp,0,0,txlen,txhei,4,4,tx_sclen,tx_schei);
22610 destroy_bitmap(txbmp);
22611 free(kill);
22612 }
22613
22614 void update_tooltip(int32_t x, int32_t y, size_and_pos const& sqr, char const* tipmsg, double scale)
22615 {
22616 update_tooltip(x,y,sqr.x,sqr.y,sqr.w*sqr.xscale,sqr.h*sqr.yscale,tipmsg,sqr.fw,sqr.fh,scale);
22617 }
22618 void update_tooltip(int32_t x, int32_t y, int32_t tx, int32_t ty, int32_t tw, int32_t th, char const* tipmsg, int fw, int fh, double scale)
22619 {
22620 if(!EnableTooltips)
22621 {
22622 return;
22623 }
22624
22625 ttip_install(ttip_global_id, tipmsg, tx, ty, tw, th, x, y, fw, fh);
22626 }
22627
22628 void ZQ_ClearQuestPath()
22629 {
22630 zc_set_config("zquest","win_last_quest",(char const*)nullptr);
22631 strcpy(filepath,"");
22632 }
22633
22634 //FFCore
22635
22636 void FFScript::init(bool for_continue)
22637 {
22638 for ( int32_t q = 0; q < wexLast; q++ ) warpex[q] = 0;
22639 numscriptdraws = 0;
22640 max_ff_rules = qr_MAX;
22641 temp_no_stepforward = 0;
22642 nostepforward = 0;
22643
22644 coreflags = 0;
22645 skip_ending_credits = 0;
22646 music_update_cond = 0;
22647 music_update_flags = 0;
22648 for ( int32_t q = 0; q < susptLAST; q++ ) { system_suspend[q] = false; }
22649
22650 //for ( int32_t q = 0; q < 512; q++ ) FF_rules[q] = 0;
22651 int32_t usr_midi_volume = usr_digi_volume = usr_sfx_volume = usr_music_volume = usr_panstyle = 0;
22652 FF_hero_action = 0;
22653 enemy_removal_point[spriteremovalY1] = -32767;
22654 enemy_removal_point[spriteremovalY2] = 32767;
22655 enemy_removal_point[spriteremovalX1] = -32767;
22656 enemy_removal_point[spriteremovalX2] = 32767;
22657 enemy_removal_point[spriteremovalZ1] = -32767;
22658 enemy_removal_point[spriteremovalZ2] = 32767;
22659
22660 for ( int32_t q = 0; q < 4; q++ )
22661 {
22662 FF_screenbounds[q] = 0;
22663 FF_screen_dimensions[q] = 0;
22664 FF_subscreen_dimensions[q] = 0;
22665 FF_eweapon_removal_bounds[q] = 0;
22666 FF_lweapon_removal_bounds[q] = 0;
22667 }
22668 for ( int32_t q = 0; q < FFSCRIPTCLASS_CLOCKS; q++ )
22669 {
22670 FF_clocks[q] = 0;
22671 }
22672 for ( int32_t q = 0; q < SCRIPT_DRAWING_RULES; q++ )
22673 {
22674 ScriptDrawingRules[q] = 0;
22675 }
22676 for ( int32_t q = 0; q < NUM_USER_MIDI_OVERRIDES; q++ )
22677 {
22678 FF_UserMidis[q] = 0;
22679 }
22680 subscreen_scroll_speed = 0; //make a define for a default and read quest override! -Z
22681 kb_typing_mode = false;
22682 initIncludePaths();
22683 }
22684
22685 void FFScript::updateIncludePaths()
22686 {
22687 includePaths.clear();
22688 int32_t pos = 0; int32_t pathnumber = 0;
22689 for ( int32_t q = 0; includePathString[pos]; ++q )
22690 {
22691 int32_t dest = 0;
22692 char buf[2048] = {0};
22693 while(includePathString[pos] != ';' && includePathString[pos])
22694 {
22695 buf[dest] = includePathString[pos];
22696 ++pos;
22697 ++dest;
22698 }
22699 ++pos;
22700 string str(buf);
22701 includePaths.push_back(str);
22702 }
22703 }
22704
22705 void FFScript::initIncludePaths()
22706 {
22707 memset(includePathString,0,sizeof(includePathString));
22708 FILE* f = fopen("includepaths.txt", "r");
22709 if(f)
22710 {
22711 int32_t pos = 0;
22712 int32_t c;
22713 do
22714 {
22715 c = fgetc(f);
22716 if(c!=EOF)
22717 includePathString[pos++] = c;
22718 }
22719 while(c!=EOF && pos<MAX_INCLUDE_PATH_CHARS);
22720 if(pos<MAX_INCLUDE_PATH_CHARS)
22721 includePathString[pos] = '\0';
22722 includePathString[MAX_INCLUDE_PATH_CHARS-1] = '\0';
22723 fclose(f);
22724 }
22725 else strcpy(includePathString, "include/;headers/;scripts/;");
22726 al_trace("Full path string is: ");
22727 safe_al_trace(includePathString);
22728 al_trace("\n");
22729 updateIncludePaths();
22730
22731 for ( size_t q = 0; q < includePaths.size(); ++q )
22732 {
22733 al_trace("Include path %zu: ",q);
22734 safe_al_trace(includePaths.at(q).c_str());
22735 al_trace("\n");
22736 }
22737 }
22738
22739 int32_t FFScript::getQRBit(int32_t rule)
22740 {
22741 return ( get_qr(rule) ? 1 : 0 );
22742 }
22743
22744 int32_t FFScript::getTime(int32_t type)
22745 {
22746 //struct tm *tm_struct = localtime(time(NULL));
22747 struct tm * tm_struct;
22748 time_t rawtime;
22749 time (&rawtime);
22750 tm_struct = localtime (&rawtime);
22751
22752 switch(type)
22753 {
22754 case curyear:
22755 {
22756 int32_t year = tm_struct->tm_year + 1900; /* year */
22757 //year format starts at 1900, so we add it to the return
22758 return year;
22759
22760 }
22761 case curmonth:
22762 {
22763 int32_t month = tm_struct->tm_mon +1; /* month */
22764 //Months start at 0, but we want 1->12
22765 return month;
22766 }
22767 case curday_month:
22768 {
22769 int32_t day_month = tm_struct->tm_mday; /* day of the month */
22770 return day_month;
22771 }
22772 case curday_week:
22773 {
22774 int32_t day_week = tm_struct->tm_wday; /* day of the week */
22775 return day_week;
22776 }
22777 case curhour:
22778 {
22779 int32_t hour = tm_struct->tm_hour; /* hours */
22780 return hour;
22781 }
22782 case curminute:
22783 {
22784 int32_t minutes = tm_struct->tm_min; /* minutes */
22785 return minutes;
22786 }
22787 case cursecond:
22788 {
22789 int32_t secs = tm_struct->tm_sec; /* seconds */
22790 return secs;
22791 }
22792 case curdayyear:
22793 {
22794 int32_t day_year = tm_struct->tm_yday; /* day in the year */
22795 return day_year;
22796 }
22797 case curDST:
22798 {
22799 int32_t isDST = tm_struct->tm_isdst; /* daylight saving time */
22800 return isDST;
22801 }
22802 default: return -1;
22803
22804 }
22805 }
22806
22807 extern const char *itemclass_help_string_defaults[itype_max];
22808
22809 /* end */
22810
22811 24576 int32_t FFScript::getQuestHeaderInfo(int32_t type)
22812 {
22813 24576 return quest_format[type];
22814 }
22815
22816 bool isSideViewGravity(int32_t t)
22817 {
22818 return (Map.CurrScr()->flags7&fSIDEVIEW) != 0;
22819 }
22820
22821
22822
22823
22824 void FFScript::ZScriptConsole(bool open)
22825 {
22826
22827
22828 #ifdef _WIN32
22829 if ( console_is_open )
22830 {
22831 zscript_coloured_console.Create("ZQuest Classic Logging Console", 600, 200);
22832 zscript_coloured_console.cls(CConsoleLoggerEx::COLOR_BACKGROUND_BLACK);
22833 zscript_coloured_console.gotoxy(0,0);
22834 zscript_coloured_console.cprintf( CConsoleLoggerEx::COLOR_BLUE | CConsoleLoggerEx::COLOR_INTENSITY |
22835 CConsoleLoggerEx::COLOR_BACKGROUND_BLACK,"ZQuest Classic Logging Console\n");
22836 }
22837 else
22838 {
22839 //close
22840 zscript_coloured_console.Close();
22841 }
22842 #endif
22843 }
22844
22845 template <typename ...Params>
22846 void FFScript::ZScriptConsole(int32_t attributes,const char *format, Params&&... params)
22847 {
22848 #ifdef _WIN32
22849 initConsole();
22850 zscript_coloured_console.cprintf( attributes, format, std::forward<Params>(params)... );
22851 #endif
22852 }
22853
22854 int32_t getpitfall(int32_t x, int32_t y){return 0;}
22855
22856 bool update_hw_pal = false;
22857 void update_hw_screen()
22858 {
22859 if (is_headless())
22860 return;
22861
22862 framecnt++;
22863
22864 zc_process_display_events();
22865 if (update_hw_pal)
22866 {
22867 zc_set_palette(RAMpal);
22868 update_hw_pal = false;
22869 }
22870
22871 render_timer_wait();
22872 render_zq();
22873 }
22874
22875 bool checkCost(int32_t ctr, int32_t amnt)
22876 {
22877 if(!game) return true;
22878 if(amnt <= 0) return true;
22879 switch (ctr)
22880 {
22881 case crMONEY: //rupees
22882 {
22883 if ( current_item_power(itype_wallet) ) return true;
22884 break;
22885 }
22886 case crMAGIC: //magic
22887 {
22888 if (get_qr(qr_ENABLEMAGIC))
22889 {
22890 return (((current_item_power(itype_magicring) > 0)
22891 ? game->get_maxmagic()
22892 : game->get_magic()+game->get_dmagic())>=amnt*game->get_magicdrainrate());
22893 }
22894 return true;
22895 }
22896 case crARROWS:
22897 {
22898 if(current_item_power(itype_quiver))
22899 return true;
22900 if(!get_qr(qr_TRUEARROWS))
22901 return checkCost(crMONEY, amnt);
22902 break;
22903 }
22904 case crBOMBS:
22905 {
22906 if(current_item_power(itype_bombbag))
22907 return true;
22908 break;
22909 }
22910 case crSBOMBS:
22911 {
22912 if(current_item_power(itype_bombbag)
22913 && itemsbuf[current_item_id(itype_bombbag)].flags & item_flag1)
22914 return true;
22915 break;
22916 }
22917 }
22918 return (game->get_counter(ctr)+game->get_dcounter(ctr)>=amnt);
22919 }
22920 bool checkmagiccost(int32_t itemid, bool checkTime)
22921 {
22922 if(itemid < 0)
22923 {
22924 return false;
22925 }
22926 itemdata const& id = itemsbuf[itemid];
22927 return checkCost(id.cost_counter[0], id.cost_amount[0])
22928 && checkCost(id.cost_counter[1], id.cost_amount[1]);
22929 }
22930 bool checkbunny(int32_t itemid)
22931 {
22932 return true;
22933 }
22934
22935 void payCost(int32_t ctr, int32_t amnt, int32_t tmr, bool ignoreTimer)
22936 {
22937 return;
22938 }
22939 void paymagiccost(int32_t itemid, bool ignoreTimer, bool onlyTimer)
22940 {
22941 return;
22942 }
22943 bool is_in_scrolling_region()
22944 {
22945 return false;
22946 }
22947
22948 void enter_sys_pal(){}
22949 void exit_sys_pal(){}
22950
22951 void replay_step_comment(std::string comment) {}
22952 bool replay_is_active() {return false;}
22953 9 bool replay_is_replaying() {return false;}
22954 bool replay_version_check(int min, int max) {return max == -1;}
22955 bool replay_is_debug() {return false;}
22956 std::string replay_get_meta_str(std::string key){return "";}
22957 int32_t item::run_script(int32_t mode){return 0;};
22958 ffcdata* slopes_getFFC(int id)
22959 {
22960 return nullptr;
22961 }
22962
22963 int calculate_test_dmap()
22964 {
22965 int dmap = -1;
22966 auto pal = Map.getcolor();
22967 int scr = Map.getCurrScr();
22968 int scrx = scr & 0x0F;
22969 for(auto q = 0; q < MAXDMAPS; ++q)
22970 {
22971 auto& dm = DMaps[q];
22972 if(dm.map != Map.getCurrMap())
22973 continue;
22974 if((dm.type&dmfTYPE)!=dmOVERW)
22975 {
22976 if(scrx < dm.xoff || scrx >= dm.xoff+8)
22977 continue;
22978 }
22979 if(dmap < 0)
22980 dmap = q; // soft-accept this, but look for better still
22981 if(pal == dm.color)
22982 {
22983 dmap = q;
22984 // found the best match we have information for, break out
22985 break;
22986 }
22987 }
22988 if(dmap < 0) dmap = 0;
22989 return dmap;
22990 }
22991
22992 #ifdef __EMSCRIPTEN__
22993 extern "C" void open_test_mode()
22994 {
22995 int dmap = calculate_test_dmap();
22996 int scr = zc_min(0x7F, Map.getCurrScr());
22997
22998 em_open_test_mode(filepath, dmap, scr, -1);
22999 }
23000
23001 extern "C" void get_shareable_url()
23002 {
23003 EM_ASM({
23004 ZC.setShareableUrl({open: UTF8ToString($0), map: $1, screen: $2});
23005 }, filepath, Map.getCurrMap(), Map.getCurrScr());
23006 }
23007 #endif
23008
23009 11 void setZScriptVersion(int32_t v){}
23010